重学JavaScript之原型链

103 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

原型

JavaScript 中是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个 prototype 属性,它的属性值是一个对象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。

当使用构造函数新建一个对象后,在这个对象的内部将包含一个指针,这个指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针被称为对象的原型。一般来说不应该获取到这个值的,但是现在浏览器中都实现了 __proto__ 属性来访问这个属性。

但是最好不要使用这个属性,因为它不是规范中规定的。可以通过 Object.getPrototypeOf() 这个方法来获取对象的原型。

原型链

当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。


放一张经典大图

1671d387e4189ec8.png

有点乱,不要紧

我们自己手画一遍

打开 excalidraw


根据刚刚的定义,构造函数都有一个 prototype 属性

image.png

使用构造函数创建的实例对象,通过 __proto__ 指向构造函数的 prototype

image.png

构造函数也是函数,它的上一级是 Function

image.png

原型对象也是对象,对象的上一级是 Object

image.png

大致可以总结出:可以通过 __proto__ 来寻找自己的上一级

把图合起来看

image.png

虽然有一些是经典图里面没有的,但是至少看起来比较简洁了。

原型链的终点

原型链的终点是 null,即 Object.prototype.__proto__=== null

原型修改、重写

function Person(name) {
    this.name = name
}
// 修改原型
Person.prototype.getName = function() {}

var p = new Person('hello')
// 实例对象通过 __proto__ 指向构造函数的 prototype
console.log(p.__proto__ === Person.prototype) // true
console.log(p.__proto__ === p.constructor.prototype) // true
// 重写原型
Person.prototype = {
    getName: function() {}
}
let p = new Person('hello')
console.log(p.__proto__ === Person.prototype)        // true

// p.constructor ===> Object
console.log(p.__proto__ === p.constructor.prototype) // false

如果希望可以成立,就要用constructor指回来

Person.prototype = {
    getName: function() {}
}
let p = new Person('hello')
p.constructor = Person
console.log(p.__proto__ === Person.prototype)        // true
console.log(p.__proto__ === p.constructor.prototype) // true

小练习🙋:

实例对象通过 proto 指向构造函数的 prototype

p.__proto__  // Person.prototype

原型对象也是对象,对象的上一级是 Object

Person.prototype.__proto__  // Object.prototype

原型对象也是对象,对象的上一级是 Object

p.__proto__.__proto__ // Object.prototype

p.__proto__.constructor ===> Person。Person.prototype:原型对象也是对象,对象的上一级是 Object

p.__proto__.constructor.prototype.__proto__ // Object.prototype

原型对象也是对象,对象的上一级是 Object

Person.prototype.constructor.prototype.__proto__ // Object.prototype
p.__proto__.constructor // Person
Person.prototype.constructor  // Person

更多练习题可以查看:juejin.cn/post/694303…