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