摘要:此貼用于記錄原型鏈相關的一些東西。在里,函數都有,對象都有,一個函數的和一個對象的就是原型,原型其實也是一個對象。如果原型鏈很長,當訪問某個屬性的時候,會話更多的時間,需要注意原型鏈不要太長。在引入的之前,函數的繼承就是通過原型來實現的。
此貼用于記錄原型鏈相關的一些東西。
在JavaScript里,函數都有prototype,對象都有__proto__,一個函數的prototype和一個對象的__proto__就是原型,原型其實也是一個對象。
一個函數的prototype和這個函數的示例對象的__proto__是同一個引用,即:
function A(){ } let a = new A(); console.log(a.__proto__ === A.prototype); //返回的是true
當調用某一個對象的方法的時候,如果找不到這個對象的方法,則會去找這個對象的原型里的方法,如果再找不到,則繼續找原型的原型的方法,一直往上找,這個就是原型鏈,如果都找不到,則會報錯。
如果原型鏈很長,當訪問某個屬性的時候,會話更多的時間,需要注意原型鏈不要太長。
在引入es6的extends之前,函數的繼承就是通過原型來實現的。下面記錄一下我理解的繼承,下面的繼承參考的是[JS繼承的實現方式
][1],他那里有完整的繼承方法。
function A(name) { this.name = name; this.f1 = function () { console.log(this.name + "正在做f1"); } } A.prototype.f2 = function () { console.log(this.name + "正在做f2"); } function B(name) { this.name = name; } B.prototype = new A(""); let b = new B("test"); b.f1(); b.f2(); console.log(b.__proto__ === B.prototype); //true console.log(b instanceof A);//true console.log(b instanceof B);//true
上述例子中,b居然是A的實例對象,也是B的實例對象,這樣其實是有問題的,需要在B.prototype = new A("");后面加上:
B.prototype.constructor = B;
優點:
1.簡單,實現容易
2.能訪問父類所有的方法和屬性
缺點:
1.要給B的prototype新增方法必須要在 new A("");之后
2.無法實現多繼承
3.沒法向父類的構造函數傳遞參數
4.實例是當前類的實例,也是父類的實例
function A(name){ this.name = name; this.f1 = function(){ console.log(this.name + "正在做f1"); } } A.prototype.f2 = function(){ console.log(this.name + "正在做f2"); } function B(name) { A.call(this, name); } let b = new B("test"); b.f1(); // b.f2();// 會報錯 console.log(b instanceof A);//false console.log(b instanceof B);//true
優點:
1.可以使用父類的屬性和方法
2.可以實現多重繼承,即可以call多個函數
3.實例對象是當前類的實例,不是父類的實例
缺點:
1.無法獲取A的prototype的屬性和方法
2.只是子類的實例,不是父類的實例
3.無法實現函數復用,每個子類都有父類實例函數的副本,影響性能(此處應該是調用call的時候會生成父類的實例副本,具體的還得再研究研究)
function A(name){ this.name = name; this.f1 = function(){ console.log(this.name + "正在做f1"); } } A.prototype.f2 = function(){ console.log(this.name + "正在做f2"); } function B(name) { A.call(this, name); } B.prototype = new A(""); //要修正prototype的constructor,為什么要修正還有待研究 B.prototype.constructor = B; let b = new B("test"); b.f1(); b.f2(); console.log(b instanceof A);//true console.log(b instanceof B);//true
優點:
1.包含了原型鏈繼承和構造繼承的優點
2.解決了原型鏈繼承的無法實現多繼承和沒法向父類的構造函數傳遞參數的缺點
3.解決了構造繼承無法獲取A的prototype的屬性和方法還有只是子類的實例,不是父類的實例的問題
缺點:
1.調用了兩次父類構造函數,生成了兩份實例(子類實例將子類原型上的那份屏蔽了)
function A(name){ this.name = name; this.f1 = function(){ console.log(this.name + "正在做f1"); } } A.prototype.f2 = function(){ console.log(this.name + "正在做f2"); } function B(name) { A.call(this, name); } (function(){ // 創建一個沒有實例方法的類 var Super = function(){}; Super.prototype = A.prototype; //將實例作為子類的原型,這樣就可以只獲取A的prototype的屬性了 B.prototype = new Super(); // B.prototype.constructor = B; })(); let b = new B("test"); b.f1(); b.f2(); console.log(b instanceof A);//true console.log(b instanceof B);//true
優點:
1.在組合繼承的基礎上,只生成了一份父類的實例,prototype也只繼承了父類的prototype,沒有繼承私有的屬性
缺點:
1.實現復雜
順便加一個知識點,當使用new關鍵字來創建對象的時候,也用到了原型相關的知識,所以也記在了這里;
假設有一個function A(name){ this.name = name; };使用new關鍵字創建一個A的實例對象let a = new A();
new關鍵字主要做了以下幾個步驟:
(1)創建一個空的對象
var obj = {};
(2)將這個對象的原型__proto__指向A的prototype
obj.__proto__ = A.prototype
(3)函數A的this指向obj;接著執行A函數
(4)將obj返回,變量a指向obj
本文主要是參考了別人的文章,寫一些自己的理解,如果有什么寫錯的地方歡迎大神來指正一下
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101767.html
摘要:調用棧就是為了到達當前執行位置所調用到的所用函數。方法測試是否至少有一個元素通過由提供的函數實現的測試返回值是終止。然而,如果存在于原型鏈上層,賦值語句的行為就會有些不同而且可能很出人意料。 typeof null 為 object 解釋 不同的對象在底層都表示為二進制,在JavaScript中二進制前三位都為0的話會被判斷為object類型,null 的二進制表示都是0,自然前三位都...
摘要:以上是面試中筆試涉及到的知識點或者后面被問到的只是點。也許是根據薪資和面試的等級來出題的。我剛面試完回家,吃了一個泡面,回憶下面試題。同時作為傳遞到構造函數,執行了一次讓構造函數里面的屬性和方法賦值了一份給。 css 如何水平垂直居中,請盡量多說幾種方法?很尷尬,我多次面試都被問到這個問題,fuck 定位(回答了)、table-cell布局、flex布局、translate+relat...
摘要:以上是面試中筆試涉及到的知識點或者后面被問到的只是點。也許是根據薪資和面試的等級來出題的。我剛面試完回家,吃了一個泡面,回憶下面試題。同時作為傳遞到構造函數,執行了一次讓構造函數里面的屬性和方法賦值了一份給。 css 如何水平垂直居中,請盡量多說幾種方法?很尷尬,我多次面試都被問到這個問題,fuck 定位(回答了)、table-cell布局、flex布局、translate+relat...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:組合使用構造函數模式和原型。構造函數用于定義實例屬性,原型鏈用于定定方法和共享的屬性。為了避免矛盾和意外的結果總是指定基數參數。 本文主要記錄平時開發遇到的知識點和小技巧 原型對象與原型鏈 JavaScritp 引擎在訪問對象的屬性時,如果在對象本身中沒有找到,則會去原型鏈中查找,如果找到,直接返回值,如果整個鏈都遍歷且沒有找到屬性,則返回 undefined.原型鏈一般實現為一個鏈表...
閱讀 1050·2021-11-22 15:35
閱讀 1685·2021-10-26 09:49
閱讀 3230·2021-09-02 15:11
閱讀 2075·2019-08-30 15:53
閱讀 2636·2019-08-30 15:53
閱讀 2917·2019-08-30 14:11
閱讀 3527·2019-08-30 12:59
閱讀 3241·2019-08-30 12:53