這篇文章帶給大家的內容是關於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影片教學】
以上是javascript現繼承的四種方式(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!