深入了解JS原型

1 构造函数存在的问题

如以下代码通过构造函数和new创建出了实例对象person1和person2。

function Person() {
    this.age = age;
    this.say = function () {
        console.log('我想飞');
    };
}
var person1 = new Person();
var person2 = new Person();
复制代码

构造函数中存在方法say()属于复杂数据类型,如下图所示每次调用时都会在开辟一个新的空间。虽然实例对象person1和person2调用的方法是同一方法,却要开辟两个相同的say()空间,如果有大量的实例对象将会造成大量的内存浪费。

image.png

2 原型对象prototype的作用

原型是什么?是对象。

原型的作用是什么?共享方法。

prototype原型对象解决了构造函数的问题,将构造函数中的方法存入构造函数的prototype原型对象中,不同的实例对象使用say()方法时,都是使用原型对象中的say(),如下图所示,大大节省了内存。

image.png

3 对象原型__proto__和构造函数constructor

3.1 __ proty __

每个实例对象都会有一个__proto__指向构造函数的 prototype 原型对象,所以我们可以通过实例对象的__proto__使用构造函数原型对象的属性和方法。如下列代码中__proto__对象原型和原型对象 prototype 是等价的。

function Person() {}
var person1 = new Person();
console.log(Person.prototype === person1.__proto__);//返回 true
复制代码

3.2 constructor

对象原型__proto__和构造函数prototype原型对象里面都有一个属性 constructor 属性 ,constructor 我们称为构造函数,因为它指回构造函数本身。
constructor 主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

注意:是可以修改的,不可靠。

4 构造函数、实例对象、原型对象三者的关系。

  • 通过构造函数Person和new创建了对象实例person1。
  • person1.__ptoto__指向构造函数Person.prototype原型对象
  • Person.prototype的constructor指向了构造函数Person

image.png

5 JS查找机制

  • 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
  • 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
  • 如果还没有就查找原型对象的原型(Object的原型对象)。
  • 依此类推一直找到 Object 为止(null)。
  • __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。

6 原型链

根据查找机制可以很轻松的搞清楚原型链,需要注意的是:

  • 在JS里,函数就是Function函数的实例对象,所有函数都是Function构造的。
  • Object.prototype是所有对象(直接或间接)的原型。

image.png

7 Function和Object的特殊性。

  • 首先Function的构造函数是自身,即Function.__proto__ === Function.prototype

  • Function也是Object的构造函数,所以Function.prototype === Object.__proto__

  • 同时Function的prototype原型对象也是Object的实例对象Function.prototype.__proto__ === Object.prototype但是Object又是Function的实例对象。Object.__proto__ === Function.prototype即你是我的对象,我是你的对象。

  • 最终的prototype原型对象属于ObjectObject.prototype.__proto__ === null

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享