# 先看代码:

function F(){}      // 构造函数
let f = new F()     // 新建实例
  • prototype是函数的原型对象
  • __proto__是每个对象都有的一个属性
  • 实例的__proto__指向的是他的构造函数的prototype
  • JS中一切都是对象,所以所有的对象、函数的__proto__最终都会指向Object这个 构造函数的prototype
  • Object.prototype的__proto__最终会指向null

# 翻译翻译:

const log = console.log
// f实例的__proto__ 指向 其构造函数F的prototype
log(f.__proto__ === F.prototype)                    // true
// F的prototype的__proto__ 指向构造函数Object的prototype
log(F.prototype.__proto__ === Object.prototype)     // true
// 所以形成的原型链关系
log(f.__proto__.__proto__ === Object.prototype)     // true
// 原型链的顶点是null
log(Object.prototype.__proto__ === null)            // true

需要注意的是

Function.__proto__指向他自己的prototype
Object.__proto__指向的是Function的prototype

  • 因为Function和Object本身也是一个构造函数
// 构造函数F的__proto__ 指向 其构造函数Function的prototype
log(F.__proto__ === Function.prototype)             // true
// Function的__proto__ 指向 Function的prototype
log(Function.__proto__ === Function.prototype)      // true
// Object的__proto__ 指向 Function的prototype   
log(Object.__proto__ === Function.prototype)        // true

# 原型链的应用:

f调用一个方法,它首先会在自己的内部寻找,如果没有,就会沿着原型链 到他的构造函数的原型对象上找,如果还没有就会沿着原型链一直往上找, 直到找不到为止。

function F(){}
let f = new F()
F.prototype.sayO = function() { log('O') }
Function.prototype.sayA = function() { log('A') }
Object.prototype.sayB = function() { log('B') }

f.sayO()        // O
f.sayA()        // 不存在sayA方法
f.sayB()        // B