千锋教育JavaScript全套视频教程(10天学会Js,前端javascrip

# 原型及继承
### 原型
#### 概述
原型是一个公共的对象空间,它里面可以储存对应的公共属性及方法.
#### 构造函数的缺陷
```js
function Person(name){
this.name = name
this.sayHello = ()=>{
console.log('hello')
} // this.sayHello = new Function.log('hello')
}
// 实例化对象
let person1 = new Person('jack')
let person2 = new Person('jack')
console.log(person1 == person2) // false
console.log(person1.name == person2.name) // true
console.log(person1.sayHello == person2.sayHello) // false
```
构造函数内如果去指定方法那么对应的每次实例化都会开辟专门的函数空间去存储对应的操作代码.那没救意味着我们实例化的对象越多,需要开辟的函数救越多,而这些函数内的操作都是一致,这就会造成对应的资源浪费.那么就会损耗对应的效率.那么解决这个问题我们就可以利用一个公共空间去存储对应的函数,那么这些函数找到的地址就是一个.而这个公共空间的名字就是原型.
**一般函数储存在原型上,属性储存在构造函数内**
#### 函数的原型
`prototype`是函数内的一个公共空间,它是一个对象.它属于函数的本事,它属于函数本事,它被称为显示原型.
**解决构造函数的缺陷,就是将对应的函数存放在对应的原型上**
###### 注意事项
- 原型上具备`constructor`属性 这个属性指向对应的构造函数
- 原型上的属性 可以使用实例化对象可以直接访问
- class更constructor一级的函数都是存放在原型上的
- 原型上一般储存对应的函数,构造函数上一般储存对应的属性
### 对象的原型
`__proto__`是属于对象的原型,实例化对象也是对象所有它同样存在.他指向*其构造函数的原型*,他被称为隐私原型.
#### 示例
```js
// __proto__是对应的对象的一个公共空间
console.log(new Person().__proto__)
// 对象的原型指向其构造函数的原型
console.log(new Person().__proto__ === Person.prototype) // true
```
#### 实现new方法
```js
// new方法实现
// 传入对应的构造函数及参数
function myNew(fn,...arg){
// 自动构建对象 (将当前的对象原型指向对应的构造函数)
let obj = {}
obj.__proto__ = fn.prototype // 显示类型
// 传入参数执行构造函数 (填充属性 属性赋值)将当前构造的对象替代里面的this
fn.apply(obj,obj) // 属性赋值
// 自动返回构造的对象
return obj
}
let newPerson = myNew(Person)
```
###### 注意事项
`__proto__`指向其构造函数的prototype
`__proto__`非javaScript标准(浏览器支持)
##### 问题
对象的原型为__proto__,它指向对应构造函数的prototype.这个构造函数的prototype也是一个对象,那么它同样也具备对应的__proto__,那么对应的构造函数的原型对象的__proto__又指向谁?
**对应的指向从当前的构造函数的prototype一直到null为止 而这个指向的过程其实是就原型链查找的过程**
### 原型链
在原型向上查找属性的过程构成的链条(不断在__proto__查找)称为原型链
##### 原型链的查找过程
- 查找自身的__proto__是否具备属性找到就返回属性值
- 不断向上查找对应的父类构造函数的prototype是否具备这个属性 找到返回值
- 一直查到Object的prototype上是否具备这个属性 找到返回属性值
- 如果Object的prototype上还没有找到就会去找null 返回undefined