摘要:老明調用了從原型中繼承來的方法繼承到了當前對象的原型中調用了從原型中擴展來的方法構造繼承基本思想借用構造函數(shù)的基本思想就是利用或者把父類中通過指定的屬性和方法復制借用到子類創(chuàng)建的實例中。
1、原型鏈繼承
核心: 將父類的實例作為子類的原型
缺點: 父類新增原型方法/原型屬性,子類都能訪問到,父類一變其它的都變了
function Person (name) { this.name = name; }; Person.prototype.getName = function () { //對原型進行擴展 return this.name; }; function Parent (age) { this.age = age; }; Parent.prototype = new Person("老明"); //這一句是關鍵 //通過構造器函數(shù)創(chuàng)建出一個新對象,把老對象的東西都拿過來。 Parent.prototype.getAge = function () { return this.age; }; // Parent.prototype.getName = function () { //可以重寫從父類繼承來的方法,會優(yōu)先調用自己的。 // console.log(222); // }; var result = new Parent(22); console.log(result.getName()); //老明 //調用了從Person原型中繼承來的方法(繼承到了當前對象的原型中) console.log(result.getAge()); //22 //調用了從Parent原型中擴展來的方法2、構造繼承
基本思想
借用構造函數(shù)的基本思想就是利用call或者apply把父類中通過this指定的屬性和方法復制(借用)到子類創(chuàng)建的實例中。
因為this對象是在運行時基于函數(shù)的執(zhí)行環(huán)境綁定的。也就是說,在全局中,this等于window,而當函數(shù)被作為某個對象的方法調用時,this等于那個對象。
call、apply 方法可將一個函數(shù)的對象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對象。
所以,這個借用構造函數(shù)就是,new對象的時候(new創(chuàng)建的時候,this指向創(chuàng)建的這個實例),創(chuàng)建了一個新的實例對象,
并且執(zhí)行Parent里面的代碼,而Parent里面用call調用了Person,也就是說把this指向改成了指向新的實例,
所以就會把Person里面的this相關屬性和方法賦值到新的實例上,而不是賦值到Person上面,
所以所有實例中就擁有了父類定義的這些this的屬性和方法。
因為屬性是綁定到this上面的,所以調用的時候才賦到相應的實例中,各個實例的值就不會互相影響了。
核心:使用父類的構造函數(shù)來增強子類實例,等于是復制父類的實例屬性給子類(沒用到原型)
缺點: 方法都在構造函數(shù)中定義, 只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法,無法實現(xiàn)函數(shù)復用,每個子類都有父類實例函數(shù)的副本,影響性能
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對象上執(zhí)行Person構造函數(shù)中定義的所有對象初始化代碼, // 結果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、組合繼承
組合繼承(所有的實例都能擁有自己的屬性,并且可以使用相同的方法,組合繼承避免了原型鏈和借用構造函數(shù)的缺陷,結合了兩個的優(yōu)點,是最常用的繼承方式)
核心:通過調用父類構造,繼承父類的屬性并保留傳參的優(yōu)點,然后再通過將父類實例作為子類原型,實現(xiàn)函數(shù)復用
缺點:調用了兩次父類構造函數(shù),生成了兩份實例(子類實例將子類原型上的那份屏蔽了)
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); //通過借用構造函數(shù)都有自己的屬性,通過原型享用公共的方法 console.log(result1.name); //老明 console.log(result1.friends); //["小李","小紅"]4、寄生組合繼承
核心:通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點
缺點:堪稱完美,但實現(xiàn)較為復雜
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 () {}; // 創(chuàng)建一個沒有實例方法的類 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);
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/103148.html
摘要:參與任何數(shù)值計算的結構都是,而且。。面向人類的理性事物,而不是機器信號。達到無刷新效果。的工作原理總是指向一個對象,具體是運行時基于函數(shù)的執(zhí)行環(huán)境動態(tài)綁定的,而非函數(shù)被聲明時的環(huán)境。原型對象上有一個屬性,該屬性指向的就是構造函數(shù)。 1.JS面向對象的理解 面向對象的三大特點:繼承、封裝、多態(tài) 1、JS中通過prototype實現(xiàn)原型繼承 2、JS對象可以通過對象冒充,實現(xiàn)多重繼承, 3...
摘要:原型鏈和構造函數(shù)是一種面向對象的語言,并且可以進行原型繼承。來了極大的支持了工程化,它的標準讓瀏覽器內部實現(xiàn)類和類的繼承構造函數(shù)構造函數(shù)調用父類構造函數(shù)現(xiàn)在瀏覽器對其支持程度還不高。 原型鏈 原型鏈比作用域鏈要好理解的多。 JavaScript中的每個對象,都有一個內置的_proto_屬性。這個屬性是編程不可見的(雖然ES6標準中開放了這個屬性,然而瀏覽器對這個屬性的可見性的支持不同)...
摘要:中的繼承并不是明確規(guī)定的,而是通過模仿實現(xiàn)的。繼承中的繼承又稱模擬類繼承。將函數(shù)抽離到全局對象中,函數(shù)內部直接通過作用域鏈查找函數(shù)。這種范式編程是基于作用域鏈,與前面講的繼承是基于原型鏈的本質區(qū)別是屬性查找方式的不同。 這一節(jié)梳理對象的繼承。 我們主要使用繼承來實現(xiàn)代碼的抽象和代碼的復用,在應用層實現(xiàn)功能的封裝。 javascript 的對象繼承方式真的是百花齊放,屬性繼承、原型繼承、...
摘要:在中,寫成類的本質基本都是構造函數(shù)原型。操作符左邊是待檢測類的對象,右邊是定義類的構造函數(shù)。不宜用在這里,我們需要知道的幾種定義類的方法,除了上面的構造函數(shù)外,還有方法用這個方法,類就是一個對象,而不是函數(shù)。 js類的基本含義 我們知道,在js中,是沒有類的概念的。類的所有實例對象都從同一個原型對象上繼承屬性,因此,原型對象是類的核心。 類是對象的抽象,而對象是類的具體實例。類是抽象的...
閱讀 1354·2021-11-23 09:51
閱讀 1690·2021-11-16 11:45
閱讀 4469·2021-10-09 09:43
閱讀 2827·2021-07-22 16:47
閱讀 1015·2019-08-27 10:55
閱讀 3525·2019-08-26 17:40
閱讀 3173·2019-08-26 11:39
閱讀 3315·2019-08-23 18:39