Javascrip复习--原型链

92 阅读2分钟

前提概念

  1. JavaScript 中,函数属于对象类型。任何一个对象都是 Object 的实例。
  2. Function所有函数对象的基础,而 Object 则是所有对象(包括函数对象)的基础。
  3. __proto__constructor 属性是对象所独有的; prototype 属性是函数所独有的,且因函数属于对象,因此函数也拥有 __proto__constructor 属性
  4. 函数的 prototype 属性值被称为该函数的原型

图形解析

image.png

将上面的图形拆分为易于理解的代码:

// 声明一个函数 Foo
var Foo = function () {};
var a = new Foo();
var b = new Foo();

// 1. Object构造函数原型的 __proto__ 属性指向null
Object.prototype.__proto__ === null
// 2. Function构造函数原型的 __proto__ 属性指向基础对象原型
Function.prototype.__proto__ === Object.prototype


// 3. 函数Foo原型的 __proto__ 属性指向基础对象原型
Foo.prototype.__proto__ === Object.prototype

// 4. 函数Foo原型的 __proto__ 属性指向基础函数原型
Foo.__proto__ === Function.prototype

// 5. 函数Foo原型的constructor属性指向Foo函数本身 
Foo.prototype.constructor === Foo
  1. 为何 Foo.prototype.__proto__ 指向 Object.prototype

    这里容易错误根据1,2 推断 Foo.prototype.__proto__ === Function.__proto__,但实际上:__proto__ 是指向创建该对象的构造函数原型,函数的原型一般是对象,

  2. 为何 4 会成立?

    每一个函数都属于原始构造函数 Function 的实例。所有函数 __proto__ 指向构造函数 Function 的原型

  3. 为何 Object.prototype.__proto__ 指向 null

    理解上面之后,这个问题首先想到的是这里不应该指向 Object.prototype 吗,实际上这里JS为了避免循环引可以为止,且 Object.prototype.__proto__null 是不可修改的。

  4. Object 是通过 Function 创建还是 FunctionObject 创建?

    // 从继承类上看难以辨别
    Object intanceof Function // true
    Function intanceof Object // true
    
    // 创建Object构造函数的 构造函数是Function
    Object.__proto__ === Function.prototype
    // 创建Function构造函数的 构造函数是Function
    Function.__proto__ === Function.prototype
    

    这里很容易认为是Object构造函数创建了Function,实际上是 Function 创建了 Object、Number、String、Date、function fn(){}等第一批构造函数,也包括他自己

进阶阅读

听风是风--原型链

听风是风--Object与Function的先后问题