一句话说清楚函数原型链

0 阅读1分钟

JS世界里,一切函数都是对象!!!

为什么?

  • 函数可以拥有属性和方法,只有对象才能添加属性和方法,基本类型不行
function fn() {};
fn.name = '函数fn的属性name' // 给函数添加属性
// 给函数添加方法
fn.say = function() {

}
  • 函数 fn instanceof Object === true
console.log(function(){} instanceof Object) // true
  • 函数有原型,有__proto__ ,整条原型链最终指向Object
function fn() {};
// 函数fn的原型__proto__指向构造函数Function.prototype
console.log(fn.__proto__ === Function.prototype) // true
//构造函数Function.prototype的原型`__proto`指向对象的Object.prototype
console.log(Function.prototype.__proto__ === Object.prototype) // true

  • Object.prototype的原型指向哪里?指向null,对象原型链的源头,根原型
// Object.prototype的原型指向哪里?
console.log(Object.prototype.__proto__ === null) // true

image.png

举例说明: tips说明一下好理解__proto__可以理解写法对象__内部属性命名习惯。

   var P = function() {};
   P.prototype.name = function() { console.log(this.name)}
   var p1 = new P(), p2 = new P();
   p1.__proto__ === P.prototype;
   p2.__proto__ === P.prototype;

image.png

// 继续如上代码
p1.__proto__ === P.prototype;
// P的原型__proto__指向Function.prototype
 P.__proto__ === Funciton.prototype // true
 //!! P和Array/RegExp/Date/String的函数区别是自定义,跟JS默认已有函数区别
 Array.__proto__ === Function.prototype // true
 RegExp.__proto__ === Function.prototype // true 
 Date.__proto__ === Function.prototype  // true
 String.__proto__ === Function.prototype // true
 //  Object 也是 Function 造的 
 Object.__proto__ === Function.prototype // true
 
 // 构造函数的原型__proto__指向构造函数的prototype
 // 这是 JavaScript 里非常经典、也很反直觉的一个设计。
 Function.__proto__ === Function.prototype  // true
 

image.png

继续特殊的往下分析,函数P——>Function——>Object——>null

// 1. Function 是由自己构造出来的 
Function.__proto__ === Function.prototype // true 
// 2. 再往上走,才到 
Object Function.prototype.__proto__ === Object.prototype // true
// 3. 顶层终点 
Object.prototype.__proto__ === null // true

image.png