面向对象
明确:面向对象是一种编程思想(何为编程思想 就是有写代码的思路 知道该怎么做 例如:登录、购物车等)
面向过程:就是将一个项目功能,分成若干个小功能或者子功能,然后从前向后一步步实现,最终完成项目。
面向对象:就是将项目功能拆分成一个个小对象,每个小对象独立完成一个功能,可以通过“调用”多个对象实现项目功能(封装)。
三大特性
封装:功能封装,便于后期调用,维护
继承:减少了代码的冗余,省略了很多重复代码
多态:不同的子类根据具体状况可以实现不同的方法,光有父类定义的方法不够灵活
面向对象(语法)
调用系统内置的构造函数创建对象
var 变量名 = new Object();
变量名.键 = 值;
// 就能得到一个空对象
var obj = new Object()
// 正常操作对象
obj.name = 'Jack'
obj.age = 18
obj.gender = '男'
字面量的方式创建一个对象
var 变量名 = {
键1:值1,
...
键n:值n
}
// 字面量方式创建对象
var obj = {
name: 'Jack',
age: 18,
gender: '男'
}
// 再来一个
var obj = {}
o2.name = 'Rose'
o2.age = 20
o2.gender = '女'
用工厂函数的方式创建对象(了解)
function 函数名() {
创建对象
返回对象
}
var 变量名1 = 函数名();
var 变量名2 = 函数名();
// 1. 先创建一个工厂函数
function createObj() {
// 手动创建一个对象
var obj = new Object()
// 手动的向对象中添加成员
obj.name = 'Jack'
obj.age = 18
obj.gender = '男'
// 手动返回一个对象
return obj
}
// 2. 使用这个工厂函数创建对象
var o1 = createObj()
var o2 = createObj()
使用自定义构造函数创建对象(重点)
function 函数名() { // 推荐首字母大写 例如系统构造函数
// 通过this.键 = 值 添加成员
// 不需要返回对象 后期通过new 关键词创建即可
}
var 变量名1 = new 函数名(); // 多学一招:小括号可以省略 推荐写上
// 1. 先创造一个构造函数
function Person(name, gender) {
// 原理:const this = {}
this.age = 18
this.name = name
this.gender = gender
// 原理:return this // 所以我们不需要return
}
// 2. 使用构造函数创建对象
var p1 = new Person('Jack', 'man')
var p2 = new Person('Rose', 'woman')
封装
概念
封装:功能封装,便于后期调用,维护
为了增加构造函数为成员的控制,会通过修饰符让一些数据不能被外部修改
语法
-
通过this来声明公有成员
-
通过var来声明私有成员
继承
概念
继承:减少了代码的冗余,省略了很多重复代码
通过继承可以给构造函数添加成员,例如:创建好构造函数,去继承一个已经存在的对象
语法
-
继承可以继承一个成员,也可以继承多个成员
-
继承单个成员:构造函数.prototype.成员名称 = 值;
-
继承多个成员:构造函数.prototype = 对象;
单个成员
<script>
/*
单成员继承: 构造函数.prototype.成员名称 = 值
多成员继承: 构造函数.prototype = 值
*/
// var obj = {
// age: 18,
// sex2: '男'
// }
// 定义人构造函数
function Person(name) {
this.name = name
}
// Person.prototype = obj
Person.prototype.age = 19
Person.prototype.sex = '男'
// 基于构造函数创建对象
var personObj1 = new Person('神龙教主')
console.log(personObj1)
console.log(personObj1.name)
console.log(personObj1.age)
console.log(personObj1.sex)
</script>
多个成员
<script>
/*
单成员继承: 构造函数.prototype.成员名称 = 值
多成员继承: 构造函数.prototype = 值
*/
var obj = {
age: 18,
sex2: '男'
}
// 定义人构造函数
function Person(name) {
this.name = name
}
Person.prototype = obj
// 基于构造函数创建对象
var personObj1 = new Person('神龙教主')
console.log(personObj1)
console.log(personObj1.name)
console.log(personObj1.age)
console.log(personObj1.sex)
console.log(personObj1.sex2)
</script>
继承(注意事项)
继承对象的成员 与 本身成员名称一致,**体现本身成员结果**
// 情况1:继承成员 和 自己的成员 一样 优秀自己的
function Person() {
this.name = '张三'
this.age = 18
}
Person.prototype.name = '李四'
var obj = new Person()
console.log(obj)
console.log(obj.name) //张三
对象和单一成员同时继承,需要先继承对象、再继承单一成员
// 情况2:继承先写多成员后写单成员
function Person() {}
var obj = {name:111,age:222}
// 先多 后单
// Person.prototype = obj // 加两个成员
// Person.prototype.sex = '女' // 加一个成员
// 先单 后多
Person.prototype.sex = '女' // 加一个成员
Person.prototype = obj // 加两个成员
var personObj1 = new Person()
console.log(personObj1.name)
console.log(personObj1.age)
console.log(personObj1.sex)
多个对象 同时继承,最后对象起作用
// 情况3:继承n个多成员 最后最后一个生效
function Person() {}
var obj1 = {name:111, age:222}
var obj2 = {name:333, age:444}
var obj3 = {name:444, age:555}
Person.prototype = obj1
Person.prototype = obj3
Person.prototype = obj2
var personObj1 = new Person()
console.log(personObj1)
原型
发现:构造函数导致浪费存储空间
function Person (name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log('hello ' + this.name);
}
}
var p1 = new Person('神龙教主', 18); //p1空间
var p2 = new Person('Jack', 16); //p2空间 但代码其实都一样
在构造函数外面定义
function sayFn() {
console.log('hello ' + this.name);
}
function Person (name, age) {
this.name = name;
this.age = age;
this.say = sayFn
}
var p1 = new Person('神龙教主', 18);
var p2 = new Person('Jack', 16);
原型对象
- 明确:JS给每一个函数,提供了一个对应的
原型对象(prototype)
- 通过函数访问语法:
函数.prototype
- 通过
new 函数
创建出来的实例对象:对象.__proto__
- 其他:原型对象有一个constructor的属性会指向自己对应的函数
function Person (name, age) {
this.name = name;
this.age = age;
// this.say = function () {
// console.log('hello ' + this.name);
// }
}
Person.prototype.say = function () {
console.log('hello ' + this.name);
}
var p1 = new Person('神龙教主', 18);
var p2 = new Person('Jack', 16);
<script>
function Person() {}
var p1 = new Person()
var p2 = new Person()
console.log(p1.__proto__ === Person.prototype) // true
console.log(p1.__proto__ === p1.__proto__) // true
</script>
原型链
-
概念:多个原型对象的集合
-
特性:
使用对象属性先用自己,找不到 .__proto__查找, 找不到 再去 .proto 里面找 一直找到
Object.prototype 里面都没有,那么就会返回 属性undefiend 方法报错未定义