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

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

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

文章插图
5. 总结总结一下:
- 我们需要牢记两点:①__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性 。
- __proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,再往上找就相当于在null上取值,会报错 。通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链 。
- prototype属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.__proto__ === Foo.prototype 。
- constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function 。
小彩蛋:实现继承(相对完美、优雅)
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] } } }}推荐阅读
- 电池|一季度动力电池装机量排行榜:宁德时代彻底无敌 以一打十
- 帮你精通Linux:Find命令高阶操作4项动作
- 一篇文章让你彻底理解回调函数
- 一文带你轻松搞懂事务隔离级别
- HashMap初始容量总结,彻底吃透位运算,简历立马多项熟练
- 理论与实践相结合彻底理解CORS
- 短视频|彻底解放双眼!消息称抖音正测试“听视频”功能:锁屏也能继续播
- 你能搞懂connectTimeout和socketTimeout的区别么?
- 两分钟彻底搞懂桶排序
- 姜片祛湿减肥20斤,做完帮你祛湿减肥
