原型 原型链

84 阅读2分钟

在js中,原型(Prototype)原型链(Prototype Chain) 是理解对象继承和属性查找的机制的核心概念,他们构成了JS基于原型的继承模型

原型

  • 每个函数都有一个prototype属性,它指向一个对象,该对象就是该函数创建的实例的原型
  • 原型对象是其他对象的“模板”,用于共享属性和方法
function a(name) {this.name = name}
var b = new a() // b是a的实例
a.prototype // => {} 每个函数都有一个prototype属性,它指向一个对象
b.__proto__ === a.prototype // => true 该对象(a.prototype)就是该函数(a())创建的实例(b)的原型(__proto__),都指向了同一个原型对象(prototype)

// .prototype 构造函数的原型
// .__proto__ 实例对象的原型

原型链

  • 多个对象通过原型相互链接形成的链条关系

  • 当访问一个属性(或方法)时,如果当前对象上没有该属性,则会沿着原型一直向上查找,一直找到原型链的顶端null为止

  • 链式查找示例

    function Person(name) {this.name = name}
    var alice = new Person()
    alice.toString() // 调用的是Object.prototype.toString() 输出 => '[object Object]'
    
    • 查找路径:

      • alice自身 -> Person.prototype -> Object.prototype -> null
    • 可以修改为

        function Person(name) {this.name = name}
        Person.prototype.toString = function () {console.log(123)}
        var alice = new Person()
        alice.toString() // 调用的是Person.prototype.toString() 输出 => 123
    
    • 手动修改原型链
    // 通过`Object.create()`拓展原型链
    const parent = { familyName: "Smith" };
    // Object.create(...): 创建返回一个新对象,并把新对象中的[[prototype]]关联到指定对象上
    const child = Object.create(parent);
    
    console.log(child) // {}
    console.log(child.familyName); // 输出: Smith
    parent.hasOwnProperty('familyName') // true
    child.hasOwnProperty('familyName') // false
    
  • 原型链的重要性

    • 原型链是JS实现继承属性共享的核心机制

构造函数

  • function a() {console.log(1)} 和 fcuntion b(name) {this.name = name},a 和 b 是否都是构造函数?
    • 构造函数不是看它是怎么定义,而是看它是怎么使用,当使用new关键词时,则该函数就可以作为构造函数,当直接使用时,则是一个普通函数
    • 实际开发中,构造函数首字母通常大写,以便区分
function Foo() {}
var f = new Foo()

f.constructor === Foo // true constructor指向其实例的构造函数本身
f.constructor.prototype === Foo.prototype // true