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?
相關文章
相關標籤/搜索