constructor、__proto__、prototype个人理解

124 阅读2分钟

constructor

对象的constructor属性指向自己的构造函数,但是一个构造函数(类)的实例可能有很多很多,如果每一个实例都要在自身挂载一大堆属性和方法,那么内存肯定浪费很严重。更重要的是很不利于维护,有什么办法解决呢?通过prototype

person1.constructor   // Person

prototype

prototype中文翻译为原型,是构造函数身上的一个对象,内部的属性和方法都会被实例共享,这样就避免了内存的浪费,同时便于统一维护管理。但是实例如何访问构造函数原型呢?通过__proto__属性!

person1.speak===Person.prototype.speak   // true

__proto__

在现代浏览器中,所有对象都会被添加一个__proto__属性指向自己的构造函数的原型,这个并不是w3c的规范。当对象自身找不到某个方法或属性时就会顺着__proto__去自己构造函数的原型上去找,找到就返回,找不到就到构造函数原型的__proto__上继续去寻找,最终如果找到Object的原型都没有找到就返回查找失败,终止条件如图所示,Object的原型的__proto__指向null,这条查找链条就是原型链

person1.__proto__===Person.prototype   // true

函数即对象

如下图可以看到,Person构造函数身上既有prototype属性,又有__proto__属性,这是为什么呢?prototype属性好理解,因为这是一个构造函数,需要有自己的原型,方便实例共享属性和方法。同时Person也是被Function构造出来的,所以也是个对象,自己的__proto__指向Function的原型。

Person.__proto__   // Function

特殊说明

  1. Function的__proto__指向自身,意思是自己构造自己。
  2. Object的原型的__proto__指向null,一切的尽头都是空🐶。之所以这么设计是为了实例沿原型链寻找属性方法时有一个终止条件,而不是进入死循环。
Function.__proto__   // Function
Object.prototype.__proto__  // null

pic