摘要:對象之間的繼承有以下幾個方法用和不推薦多帶帶使用,定義在中的屬性和方法不能繼承模式注意需要先繼承后定義傳統模式推薦,關鍵點是以及重新改變利用空對象間接繼承只繼承中的屬性,關鍵點在于利用一個空的構造函數當中介拷貝繼承不推薦多帶帶使用,循環逐一拷貝
對象之間的繼承有以下幾個方法:
用call和apply(不推薦多帶帶使用,定義在prototype中的屬性和方法不能繼承)
prototype模式(注意prototype需要先繼承后定義)
傳統prototype模式(推薦,關鍵點是Child.prototype = new Parent.prototype以及重新改變Child.prototype.constructor)
利用空對象間接繼承(只繼承prototype中的屬性,關鍵點在于利用一個空的構造函數當中介)
拷貝繼承(不推薦多帶帶使用,for循環逐一拷貝)
以上推薦使用傳統prototype模式以及call和apply與拷貝繼承相配合的模式
用call和apply
function Chinese() { this.nationality = "Chinese"; } function Person(name, age) { Chinese.apply(this); //這里改變了Chinese中this的指向 this.name = name; this.age = age; } var p1 = new Person("Oli", 18); console.log(p1.nationality); //Chinese
傳統prototype模式
function Chinese() { this.nationality = "Chinese"; } function Person(name, age) { this.name = name; this.age = age; } Person.prototype = new Chinese(); //這里因為在prototype中使用了new,則會指向Chinese console.log(Person.prototype.constructor); //Chinese(){} Person.prototype.constructor = Person; //這里需要把constructor構造函數重新改為Person console.log(Person.prototype.constructor); //Person(){} var p1 = new Person("Oli", 18); console.log(p1.nationality); //Chinese
需要注意的是:在繼承中,如果替換了prototype,那么新的prototype必須修改constructor屬性,將這個屬性指回到原來的構造函數。
利用空對象間接繼承
function Chinese() {} Chinese.prototype.nationality = "Chinese"; function Person(name, age) { this.name = name; this.age = age; } function F(){}; //空對象幾乎不占用內存 F.prototype = Chinese.prototype; Person.prototype = new F(); Person.prototype.constructor = Person; Person.prototype.sayName = function() { //Person的prototype中的方法和屬性需要在繼承之后定義 console.log(this.name); }; var p1 = new Person("Oli", 18); console.log(p1.nationality); //Chinese p1.sayName(); //Oli
可以將該方法定義為函數:
function extend(Child, Parent) { var F = function() {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; //用于訪問父對象的prototype,可用可不用 }
舉例:
function extend(Child, Parent) { var F = function() {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; } function Chinese() {} Chinese.prototype.nationality = "Chinese"; function Person(name, age) { this.name = name; this.age = age; } extend(Person, Chinese); Person.prototype.sayName = function() { console.log(this.name); }; var p1 = new Person("Oli", 18); console.log(p1.nationality); //Chinese p1.sayName(); //Oli
拷貝繼承
使用下面的函數逐一將prototype的屬性和函數拷貝到對象中:
function extend(Child, Parent) { var p = Parent.prototype; var c = Child.prototype; for (var i in p) { c[i] = p[i]; } c.uber = p; }
不需要先繼承后定義
傳統prototype模式繼承(例子)
function Parent() { this.name = "thisIsName"; } Parent.prototype.sayName = function() { return this.name; }; function Child() { this.age = "thisIsAge"; } Child.prototype = new Parent(); Child.prototype.constructor = Child; Child.prototype.sayAge = function() { return this.age; }; var c = new Child(); console.log(c.name); console.log(c.age); console.log(c.sayName()); console.log(c.sayAge());
call和apply與拷貝繼承相配合(例子)
function extend(C, P) { var p = P.prototype; var c = C.prototype; for(var i in p){ c[i] = p[i]; } c.uber = p; } function Parent() { this.name = "thisIsName"; } Parent.prototype.sayName = function() { return this.name; }; function Child() { Parent.apply(this); //繼承構造函數內的屬性和方法 this.age = "thisIsAge"; } Child.prototype.sayAge = function() { return this.age; }; extend(Child, Parent); //不需要先繼承后定義 var c = new Child(); console.log(c.name); console.log(c.age); console.log(c.sayName()); console.log(c.sayAge());
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79165.html
摘要:原型對象是由創建的,因此原型對象的構造函數是構造函數也可以是稱為對象,原型對象也就繼承了其生父構造函數中的數據,也同時繼承了原型對象的數據。當然這條原型鏈中的數據,會被還是還是這類構造函數繼承,但是不會被這些繼承,他們不處于同一個鏈條上。 js中,Function的本質是什么?Object的本質又是什么?js中有幾條原型鏈? showImg(https://segmentfault.c...
摘要:創建自定義的構造函數之后,其原型對象只會取得屬性,其他方法都是從繼承來的。優缺點寄生式繼承在主要考慮對象而不是創建自定義類型和構造函數時,是十分有用的。 原文鏈接:https://kongchenglc.coding.me... 1.原型鏈 ??js的繼承機制不同于傳統的面向對象語言,采用原型鏈實現繼承,基本思想是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。理解原型鏈必須先理...
摘要:是完全的面向對象語言,它們通過類的形式組織函數和變量,使之不能脫離對象存在。而在基于原型的面向對象方式中,對象則是依靠構造器利用原型構造出來的。 JavaScript 函數式腳本語言特性以及其看似隨意的編寫風格,導致長期以來人們對這一門語言的誤解,即認為 JavaScript 不是一門面向對象的語言,或者只是部分具備一些面向對象的特征。本文將回歸面向對象本意,從對語言感悟的角度闡述為什...
摘要:問題修改實例的,即修改了構造函數的原型對象的共享屬性到此處,涉及到的內容大家可以再回頭捋一遍,理解了就會覺得醍醐灌頂。 開場白 大三下學期結束時候,一個人跑到帝都來參加各廠的面試,免不了的面試過程中經常被問到的問題就是JS中如何實現繼承,當時的自己也是背熟了實現繼承的各種方法,回過頭來想想卻不知道__proto__是什么,prototype是什么,以及各種繼承方法的優點和缺點,想必有好...
摘要:通常有這兩種繼承方式接口繼承和實現繼承。理解繼承的工作是通過調用函數實現的,所以是寄生,將繼承工作寄托給別人做,自己只是做增強工作。適用基于某個對象或某些信息來創建對象,而不考慮自定義類型和構造函數。 一、繼承的概念 繼承,是面向對象語言的一個重要概念。通常有這兩種繼承方式:接口繼承和實現繼承。接口繼承只繼承方法簽名,而實現繼承則繼承實際的方法。 《JS高程》里提到:由于函數沒有簽名,...
閱讀 3021·2021-11-12 10:36
閱讀 4726·2021-09-22 10:57
閱讀 1558·2021-09-22 10:53
閱讀 2636·2019-08-30 15:55
閱讀 3493·2019-08-29 17:00
閱讀 3352·2019-08-29 16:36
閱讀 2463·2019-08-29 13:46
閱讀 1348·2019-08-26 11:45