您好,登錄后才能下訂單哦!
這篇文章主要介紹了javascript現繼承的方式有哪些,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
1、原型鏈繼承
核心: 將父類的實例作為子類的原型
缺點: 父類新增原型方法/原型屬性,子類都能訪問到,父類一變其它的都變了
function Person (name) { this.name = name; }; Person.prototype.getName = function () { //對原型進行擴展 return this.name; }; function Parent (age) { this.age = age; }; Parent.prototype = new Person('老明'); //這一句是關鍵 //通過構造器函數創建出一個新對象,把老對象的東西都拿過來。 Parent.prototype.getAge = function () { return this.age; }; // Parent.prototype.getName = function () { //可以重寫從父類繼承來的方法,會優先調用自己的。 // console.log(222); // }; var result = new Parent(22); console.log(result.getName()); //老明 //調用了從Person原型中繼承來的方法(繼承到了當前對象的原型中) console.log(result.getAge()); //22 //調用了從Parent原型中擴展來的方法
2、構造繼承
基本思想
借用構造函數的基本思想就是利用call
或者apply
把父類中通過this
指定的屬性和方法復制(借用)到子類創建的實例中。
因為this
對象是在運行時基于函數的執行環境綁定的。也就是說,在全局中,this
等于window
,而當函數被作為某個對象的方法調用時,this
等于那個對象。call
、apply
方法可將一個函數的對象上下文從初始的上下文改變為由 thisObj 指定的新對象。
所以,這個借用構造函數就是,new
對象的時候(new創建的時候,this
指向創建的這個實例),創建了一個新的實例對象,
并且執行Parent
里面的代碼,而Parent
里面用call
調用了Person
,也就是說把this
指向改成了指向新的實例,
所以就會把Person
里面的this
相關屬性和方法賦值到新的實例上,而不是賦值到Person
上面,
所以所有實例中就擁有了父類定義的這些this
的屬性和方法。
因為屬性是綁定到this
上面的,所以調用的時候才賦到相應的實例中,各個實例的值就不會互相影響了。
核心:使用父類的構造函數來增強子類實例,等于是復制父類的實例屬性給子類(沒用到原型)
缺點: 方法都在構造函數中定義, 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法,無法實現函數復用,每個子類都有父類實例函數的副本,影響性能
function Person (name) { this.name = name; this.friends = ['小李','小紅']; this.getName = function () { return this.name; } }; // Person.prototype.geSex = function () { //對原型進行擴展的方法就無法復用了 // console.log("男"); // }; function Parent = (age) { Person.call(this,'老明'); //這一句是核心關鍵 //這樣就會在新parent對象上執行Person構造函數中定義的所有對象初始化代碼, // 結果parent的每個實例都會具有自己的friends屬性的副本 this.age = age; }; var result = new Parent(23); console.log(result.name); //老明 console.log(result.friends); //["小李", "小紅"] console.log(result.getName()); //老明 console.log(result.age); //23 console.log(result.getSex()); //這個會報錯,調用不到父原型上面擴展的方法
3、組合繼承
組合繼承(所有的實例都能擁有自己的屬性,并且可以使用相同的方法,組合繼承避免了原型鏈和借用構造函數的缺陷,結合了兩個的優點,是最常用的繼承方式)
核心:通過調用父類構造,繼承父類的屬性并保留傳參的優點,然后再通過將父類實例作為子類原型,實現函數復用
缺點:調用了兩次父類構造函數,生成了兩份實例(子類實例將子類原型上的那份屏蔽了)
function Person (name) { this.name = name; this.friends = ['小李','小紅']; }; Person.prototype.getName = function () { return this.name; }; function Parent (age) { Person.call(this,'老明'); //這一步很關鍵 this.age = age; }; Parent.prototype = new Person('老明'); //這一步也很關鍵 var result = new Parent(24); console.log(result.name); //老明 result.friends.push("小智"); // console.log(result.friends); //['小李','小紅','小智'] console.log(result.getName()); //老明 console.log(result.age); //24 var result1 = new Parent(25); //通過借用構造函數都有自己的屬性,通過原型享用公共的方法 console.log(result1.name); //老明 console.log(result1.friends); //['小李','小紅']
4、寄生組合繼承
核心:通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點
缺點:堪稱完美,但實現較為復雜
function Person(name) { this.name = name; this.friends = ['小李','小紅']; } Person.prototype.getName = function () { return this.name; }; function Parent(age) { Person.call(this,"老明"); this.age = age; } (function () { var Super = function () {}; // 創建一個沒有實例方法的類 Super.prototype = Person.prototype; Parent.prototype = new Super(); //將實例作為子類的原型 })(); var result = new Parent(23); console.log(result.name); console.log(result.friends); console.log(result.getName()); console.log(result.age);
感謝你能夠認真閱讀完這篇文章,希望小編分享javascript現繼承的方式有哪些內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。