原型链

  1. function Fn(){}
  2. const fn = new Fn();
  3. fn.__proto__ === Fn.prototype //true
  4. // __proto__ 隐式原型
  5. // prototype 显式原型
  • 每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
  • 只有函数才有 prototype 属性


当你创建函数时,JS会为这个函数自动添加prototype属性,其值是一个有 constructor属性的对象,不是空对象。而一旦你把这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JS就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法 (实例通过设置自己的__proto__指向承构造函数的prototype来实现这种继承)。

【4】原型 - 图1

new

new做了什么?

  • 创建一个空对象,这个对象将会作为执行 new 构造函数 () 之后,返回的对象实例。
  • 将上面创建的空对象的原型(proto),指向构造函数的 prototype 属性。
  • 将这个空对象赋值给构造函数内部的 this,并执行构造函数逻辑。
  • 根据构造函数执行逻辑,返回第一步创建的对象或者构造函数的显式返回值。 ```javascript function Person(name) { this.name = name }

// 使用 const person = new newFunc(Person, ‘lucas’)

  1. new实现:
  2. ```javascript
  3. function newFunc(Fn, ...args) {
  4. const obj = {};
  5. obj.__proto__ = Fn.prototype;
  6. const result = Fn.apply(obj, args)
  7. return (typeof result === 'object' && result != null) ? result : obj
  8. }
  1. //构造函数如果有显式返回值,且返回值为对象类型,那么构造函数返回结果不再是目标实例。
  2. function Person(name) {
  3. this.name = name
  4. return {1: 1}
  5. }
  6. const person = new Person(Person, 'lucas')
  7. console.log(person)

Object和Function

  1. Object instanceof Function // true
  2. Function instanceof Object // true
  • 所有对象均从Object.prototype继承属性
  • Function.prototypeFunction.__proto__为同一对象。
  • Function.prototype继承于Object.prototype
  • Object本身是个(构造)函数,是Function的实例(对象)

    先有**Object.prototype**(原型链顶端),**Function.prototype**继承**Object.prototype**而产生,最后,**Function****Object**和其它构造函数继承**Function.prototype**而产生。

【4】原型 - 图2

理解

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

Function.proto === Function.prototype // true

Function.prototype.proto === Object.prototype // true

Object.prototype.proto === null ```