js实现继承的方法中为什么老是要修正constructor方法的指向呢?

问题引入

最近看了许多关于js继承实现的相关文章,许多实现方式中都会存在这么一行代码:javascript

A.prototype.constructor = A

因而感到好奇,这行代码的实际意义是什么?若是没有的话,还能达到继承的目的吗?html

前置知识

为了熟悉javascript中与原型相关的几个基本概念,能够参看这篇文章JavaScript深刻之从原型到原型链,做者写的十分简明易懂。
摘自原文中的总结图片java

读了文章之后能够知道,在方法(构造函数)上存在一个叫作prototype的属性,这个属性是一个对象;方法结合new关键字能够生成实例,生成的每一份实例上都会有一个叫作__proto__的属性,这个属性也是指向生成该实例的方法上的prototype属性;原型对象(即prototype这个对象)上也存在一个特别的属性,即constructor,这个属性指向的方法自己。编程

回到问题自己

咱们先来回答第二个问题:若是没有这行代码,还能到达继承的目的吗?
看一个常见的组合继承的实现方式,代码以下:segmentfault

function Animal(name) {
    this.name = name || '';
    console.log('Animal called.');
}
Animal.prototype.showName = function() {
    console.log('Name is: ', this.name);
}
function Cat(name, age) {
    Animal.call(this, name);
    this.age = age || 1;
    console.log('Cat called.');
}
Cat.prototype = new Animal();
// Cat.prototype.constructor = Cat;    // 注释掉修正constructor方法的指向的这一行
Cat.prototype.showAge = function() {
    console.log('Age is: ', this.age);
}

var cat = new Cat('meow', 3);
console.log(cat.name);    // meow
cat.showName();          // Name is: meow
console.log(cat.age);    // 3
cat.showAge();           // Age is: 3

能够看到,继承的效果依然是达到了。因此,我以为答案应该是能。函数


咱们再来看第一个问题,注释掉的这行代码的意义是什么呢?为何大部分的实现方式中都建议咱们修正这个constructor的指向呢?
网上搜索后找到这篇文章: 为何要作A.prototype.constructor=A这样的修正?, 并由此进一步的查看了Stack Overflow上的这篇问答: What it the significance of the Javascript constructor property?
因此,最重要的修正意义应该仍是针对显示调用的时候。
接着刚刚的代码来看:this

cat.__proto__.constructor  // 这个属性指向的应该是 Animal 构造函数,若是咱们以前修正了constructor的指向的话,那么这里才会真的指向到 Cat 的构造函数

// 假设咱们想要构造一个新的实例cat2,而且咱们不知道对应的构造函数的名称是什么,不过好在咱们刚刚已经有一个实例cat了(好吧,我知道这种假设比较2 -_-|||)
var cat2 = new cat.__proto__.constructor();  // Animal called (这里只有Animal的构造函数被调用了)
cat2.age;    // undefined  (由于在Animal构造函数中不存在age属性)

好吧,我认可这种场景比较少见。可是,万一有呢?因此个人建议是,咱们应该保留这种修正constructor的写法。spa


后记

在知乎的一篇问答中看到一种说法prototype

constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。因为constructor属性是能够变动的,因此未必真的指向对象的构造函数,只是一个提示。不过,从编程习惯上,咱们应该尽可能让对象的constructor指向其构造函数,以维持这个惯例。

做者:贺师俊
连接:https://www.zhihu.com/questio...
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。设计

参考文章

  1. JavaScript深刻之从原型到原型链
  2. 为何要作A.prototype.constructor=A这样的修正?
  3. What it the significance of the Javascript constructor property?
相关文章
相关标签/搜索