1. 面向对象和面向过程
-
注意:面向对象不是一个新语法,它是一种开发的思想
-
面向对象其实就是面向过程的高度封装
-
工厂函数:本质上就是写一个函数,让这个函数帮我们生产对象 * 手动创建一个对象
js const obj = {}* 手动向对象上添加一些属性js obj.name = name obj.age = age* 手动返回这个对象js return obj -
自定义构造函数 * 自定义构造函数本质上就是一个函数 * 自动帮我们创建一个对象 * 在手动向对象上添加属性,自动创建的对象可以使用this(指向刚刚那个对象)或者
js this.name = name this.age = age* 自动返回这个对象
* 调用方法
```js
function a ('要接收的形参') {...}
const b = new a('要传递的实参')
```
* 注意事项
```js
构造函数的首字母大写(建议,只是为了和普通函数作区分)
构造函数必须和new关键字连用
构造函数在调用的时候,如果不需要参数在调用时可以不加小括号
构造函数内部的this指向自动创建出来的对象
构造函数内部会自动返回一个对象所以不需要我们在书写return,如果返回的是基本数据类型那么写了跟没写没有意义,如果返回的是引用数据类型写了之后构造函数就没有意义了
调用构函数前需要加上new关键字,这个过程叫做实例化,得到的对象叫做实例化对象
function fn2 (q){
console.log(q)
}
function fn (name,age){
this.name = name
this.age = age
this.fn1 = fn2 // 此时fn1就是把fn2的地址传递进去,fn1就是一个函数
}
function fn2 (q){
return(console.log(q))
}
function fn (name,age,s){
this.name = name
this.age = age
this.fn1 = fn2(s) // 此时fn1接受的是fn2调用完成结果的返回值,fn1是一个返回值不是一个函数
}
```
2. 构造函数的弊端
- 如果内部的某个属性是函数,在实例化对象的时候都会创建一个函数,创建多少个实例化对象就会创建多少个函数
3. 原型
-
每一个函数(也包括构造函数)都有一个属性 prototype 这个属性指向一个地址,这个地址是一个对象,我们叫这个对象为原型(原型对象)
-
这个原型对象中有一个属性constructor,这个属性的属性值是一个函数,指向了这个原型的函数
-
添加到原型上的方法(函数),目的是给实例化对象使用的,不是给构造函数使用的
-
每一个对象上都有一个属性__proto__(两个下划线),这个属性内有一个地址,这个地址就是自己构造函数的原型对象
-
构造函数中放属性,原型中放函数,避免内存浪费问题
4. ES6 class类
-
因为构造函数需要用new关键字连用,但是不放在一起也可以用,不会报错
-
构造函数和原型明明是一个东西但是却要分开写
-
语法:class 类名 {}
class person {
// 构造器,类似于构造函数的构造体
constructor(){ // constructor这是一个构造器里面放构造函数内原本写的内容
}
Tab (){
}
}
new person() // 必须加new
5. 原型拓展
- 不是我们自己写的就是内置构造函数
6. 原型链
-
使用__proto__形成的链型结构
-
对象的访问规则 * 在访问对象的某一个属性时会现在对象的内部或者自身查找,找到直接使用,若是找不到则会顺着__proto__去到自己的构造函数的原型对象查找一直到objec.prototype,如果没有返回一个undefined
-
在JS中只要是一个函数就是Function的实例,只要是一个数组就是Array的实例,只要是一个对象就是Object的实例