摘要:由于屬性是可以變更的,所以未必真的指向對象的構造函數(shù),只是一個提示。不過,從編程習慣上,我們應該盡量讓對象的指向其構造函數(shù),以維持這個慣例。
問題引入
最近看了許多關于js繼承實現(xiàn)的相關文章,許多實現(xiàn)方式中都會存在這么一行代碼:
A.prototype.constructor = A
于是感到好奇,這行代碼的實際意義是什么?如果沒有的話,還能達到繼承的目的嗎?
前置知識為了熟悉javascript中與原型相關的幾個基本概念,可以參看這篇文章JavaScript深入之從原型到原型鏈,作者寫的十分簡明易懂。
讀了文章以后可以知道,在方法(構造函數(shù))上存在一個叫做prototype的屬性,這個屬性是一個對象;方法結合new關鍵字可以生成實例,生成的每一份實例上都會有一個叫做__proto__的屬性,這個屬性也是指向生成該實例的方法上的prototype屬性;原型對象(即prototype這個對象)上也存在一個特別的屬性,即constructor,這個屬性指向的方法本身。
回到問題本身我們先來回答第二個問題:如果沒有這行代碼,還能到達繼承的目的嗎?
看一個常見的組合繼承的實現(xiàn)方式,代碼如下:
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
可以看到,繼承的效果依然是達到了。所以,我覺得答案應該是能。
我們再來看第一個問題,注釋掉的這行代碼的意義是什么呢?為什么大部分的實現(xiàn)方式中都建議我們修正這個constructor的指向呢?
網(wǎng)上搜索后找到這篇文章: 為什么要做A.prototype.constructor=A這樣的修正?, 并由此進一步的查看了Stack Overflow上的這篇問答: What it the significance of the Javascript constructor property?
所以,最重要的修正意義應該還是針對顯示調(diào)用的時候。
接著剛剛的代碼來看:
cat.__proto__.constructor // 這個屬性指向的應該是 Animal 構造函數(shù),如果我們之前修正了constructor的指向的話,那么這里才會真的指向到 Cat 的構造函數(shù) // 假設我們想要構造一個新的實例cat2,并且我們不知道對應的構造函數(shù)的名稱是什么,不過好在我們剛剛已經(jīng)有一個實例cat了(好吧,我知道這種假設比較2 -_-|||) var cat2 = new cat.__proto__.constructor(); // Animal called (這里只有Animal的構造函數(shù)被調(diào)用了) cat2.age; // undefined (因為在Animal構造函數(shù)中不存在age屬性)
好吧,我承認這種場景比較少見。但是,萬一有呢?所以我的建議是,我們應該保留這種修正constructor的寫法。
后記在知乎的一篇問答中看到一種說法
constructor其實沒有什么用處,只是JavaScript語言設計的歷史遺留物。由于constructor屬性是可以變更的,所以未必真的指向對象的構造函數(shù),只是一個提示。不過,從編程習慣上,我們應該盡量讓對象的constructor指向其構造函數(shù),以維持這個慣例。
作者:賀師俊
鏈接:https://www.zhihu.com/questio...
來源:知乎
著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。
JavaScript深入之從原型到原型鏈
為什么要做A.prototype.constructor=A這樣的修正?
What it the significance of the Javascript constructor property?
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97020.html
摘要:原文相信很多才接觸前端的小伙伴甚至工作幾年的前端小伙伴對這個操作符的了解還停留在一知半解的地步,比較模糊。 原文:http://blog.xieyangogo.cn/201... 相信很多才接觸前端的小伙伴甚至工作幾年的前端小伙伴對new這個操作符的了解還停留在一知半解的地步,比較模糊。就比如前不久接觸到一個入職兩年的前端小伙伴,他告訴我new是用來創(chuàng)建對象的,無可厚非,可能很多人都...
類繼承 看類繼承前,先回顧構造函數(shù)怎么實現(xiàn)對象的繼承的 function F() { this.a = 1; } function Son() { F.call(this); } function inherit(S, F) { S.protot...
摘要:構造函數(shù)的兩個特征函數(shù)內(nèi)部使用了,指向所要生成的對象實例。將一個空對象的指向構造函數(shù)的屬性,這個對象就是要返回的實例對象。用面向對象開發(fā)時,把要生成的實例對象的特有屬性放到構造函數(shù)內(nèi),把共有的方法放到構造函數(shù)的里面。 JS中面向對象的概念 面向對象OOP是一種組織代碼結構、實現(xiàn)功能過程的思維方式。它將真實世界各種復雜的關系,抽象為一個個對象,然后由對象之間的分工與合作,完成對真實世界的...
摘要:原型鏈構造函數(shù)原型實例的關系每個構造函數(shù)都有一個原型對象,原型對象都包含一個指向構造函數(shù)的指針,實例有一個指向原型對象的指針構造函數(shù)原型對象構造函數(shù)構造函數(shù)操作符實例對象構造函數(shù)實例對象原型對象如果試 原型鏈 構造函數(shù)/原型/實例 的關系 每個構造函數(shù)都有一個原型對象,原型對象都包含一個指向構造函數(shù)的指針,實例有一個指向原型對象的指針 構造函數(shù) --(prototype)-->...
閱讀 3933·2021-09-22 10:02
閱讀 3365·2019-08-30 15:52
閱讀 3061·2019-08-30 12:51
閱讀 755·2019-08-30 11:08
閱讀 2065·2019-08-29 15:18
閱讀 3106·2019-08-29 12:13
閱讀 3592·2019-08-29 11:29
閱讀 1872·2019-08-29 11:13