帮你彻底搞懂 JS 中的 prototype、__proto__与constructor( 二 )


4. constructor属性最后,我们来看一下 constructor 属性:

帮你彻底搞懂 JS 中的 prototype、__proto__与constructor

文章插图
 
  constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数,每个对象都有构造函数(本身拥有或继承而来,继承而来的要结合__proto__属性查看会更清楚点,如下图所示),从上图中可以看出Function这个对象比较特殊,它的构造函数就是它自己(因为Function可以看成是一个函数,也可以是一个对象),所有函数和对象最终都是由Function构造函数得来,所以constructor属性的终点就是Function这个函数 。
帮你彻底搞懂 JS 中的 prototype、__proto__与constructor

文章插图
 
  感谢网友的指出,这里解释一下上段中**“每个对象都有构造函数”**这句话 。这里的意思是每个对象都可以找到其对应的constructor,因为创建对象的前提是需要有constructor,而这个constructor可能是对象自己本身显式定义的或者通过__proto__在原型链中找到的 。而单从constructor这个属性来讲,只有prototype对象才有 。每个函数在创建的时候,JS会同时创建一个该函数对应的prototype对象,而函数创建的对象.__proto__ === 该函数.prototype,该函数.prototype.constructor===该函数本身,故通过函数创建的对象即使自己没有constructor属性,它也能通过__proto__找到对应的constructor,所以任何对象最终都可以找到其构造函数(null如果当成对象的话,将null除外) 。如下:
帮你彻底搞懂 JS 中的 prototype、__proto__与constructor

文章插图
 
5. 总结总结一下:
  1. 我们需要牢记两点:①__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性 。
  2. __proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,再往上找就相当于在null上取值,会报错 。通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链 。
  3. prototype属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.__proto__ === Foo.prototype 。
  4. constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function 。
本文就此结束了,希望对那些对JS中的prototype、__proto__与constructor属性有困惑的同学有所帮助 。
小彩蛋:实现继承(相对完美、优雅)
function inherit(Child, Parent) {     // 继承原型上的属性     Child.prototype = Object.create(Parent.prototype)     // 修复 constructor    Child.prototype.constructor = Child    // 存储超类    Child.super = Parent    // 静态属性继承    if (Object.setPrototypeOf) {        // setPrototypeOf es6        Object.setPrototypeOf(Child, Parent)    } else if (Child.__proto__) {        // __proto__ es6 引入,但是部分浏览器早已支持        Child.__proto__ = Parent    } else {        // 兼容 IE10 等陈旧浏览器        // 将 Parent 上的静态属性和方法拷贝一份到 Child 上,不会覆盖 Child 上的方法        for (var k in Parent) {            if (Parent.hasOwnProperty(k) && !(k in Child)) {                Child[k] = Parent[k]            }        }    }}



推荐阅读