原型链
function Fn(){}const fn = new Fn();fn.__proto__ === Fn.prototype //true// __proto__ 隐式原型// prototype 显式原型
- 每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
- 只有函数才有 prototype 属性
当你创建函数时,JS会为这个函数自动添加
prototype属性,其值是一个有constructor属性的对象,不是空对象。而一旦你把这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JS就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法 (实例通过设置自己的__proto__指向承构造函数的prototype来实现这种继承)。

new
new做了什么?
- 创建一个空对象,这个对象将会作为执行 new 构造函数 () 之后,返回的对象实例。
- 将上面创建的空对象的原型(proto),指向构造函数的 prototype 属性。
- 将这个空对象赋值给构造函数内部的 this,并执行构造函数逻辑。
- 根据构造函数执行逻辑,返回第一步创建的对象或者构造函数的显式返回值。 ```javascript function Person(name) { this.name = name }
// 使用 const person = new newFunc(Person, ‘lucas’)
new实现:```javascriptfunction newFunc(Fn, ...args) {const obj = {};obj.__proto__ = Fn.prototype;const result = Fn.apply(obj, args)return (typeof result === 'object' && result != null) ? result : obj}
//构造函数如果有显式返回值,且返回值为对象类型,那么构造函数返回结果不再是目标实例。function Person(name) {this.name = namereturn {1: 1}}const person = new Person(Person, 'lucas')console.log(person)
Object和Function
Object instanceof Function // trueFunction instanceof Object // true
- 所有对象均从
Object.prototype继承属性 Function.prototype和Function.__proto__为同一对象。Function.prototype继承于Object.prototypeObject本身是个(构造)函数,是Function的实例(对象)先有
**Object.prototype**(原型链顶端),**Function.prototype**继承**Object.prototype**而产生,最后,**Function**和**Object**和其它构造函数继承**Function.prototype**而产生。

理解
- prototype是构造函数的属性,指向属于该构造函数的原型对象
- proto是任何对象的属性,指向该对象的构造函数的原型对象
- prototype和proto之间的唯一区别就在于前者是构造函数的属性,而后者是对象的属性
- 构造函数也是对象,也有proto属性,所有构造函数的proto的属性指向构造函数Function()的原型对象
- 原型对象是单纯的对象,其proto_属性指向构造函数Obejct()的原型对象 ```javascript Object._proto === Function.prototype // true
Function.proto === Function.prototype // true
Function.prototype.proto === Object.prototype // true
Object.prototype.proto === null
```
