亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

深入理解 javaScript 原型繼承

瀏覽:2日期:2023-11-15 09:25:32
繼承的本質(zhì):重用

在探討 javaScript 的原型繼承之前,先不妨想想為什么要繼承?

考慮一個(gè)場(chǎng)景,如果我們有兩個(gè)對(duì)象,它們一部分屬性相同,另一部屬性不同。通常一個(gè)好的設(shè)計(jì)方案是將相同邏輯抽出來(lái),實(shí)現(xiàn)重用。

以 xiaoMing liLei 兩位同學(xué)舉例。這兩位同學(xué)有自己的名字,并且會(huì)介紹自己。抽象為程序?qū)ο?,可以做如下表示?/p>

var xiaoMing = { name : 'xiaoMing', hello : function(){ console.log( ’Hello, my name is ’+ this.name + ’.’); }}var liLei = { name : 'liLei', hello : function(){ console.log( ’Hello, my name is ’+ this.name + ’.’); }}

使用過(guò) java 的同學(xué),可能第一眼就想到了用面向?qū)ο髞?lái)解決這個(gè)問(wèn)題。創(chuàng)造一個(gè) Person 的類,然后實(shí)例化 xiaoMing 和 liLei 兩個(gè)對(duì)象。在 ES6 中也有類似于 java 中類的概念: class 。

下面使用 ES6 的語(yǔ)法,用面向?qū)ο蟮乃悸穪?lái)重構(gòu)上面的代碼。

class Person { constructor(name){ this.name = name } hello(){ console.log(this.name); }}var xiaoMing = new Person(’xiaoMing’);var liLei = new Person(’liLei’);

可以看到,使用類創(chuàng)建對(duì)象,達(dá)到了重用的目的。它基于的邏輯是,兩個(gè)或多個(gè)對(duì)象的結(jié)構(gòu)功能類似,可以抽象出一個(gè)模板,依照模板復(fù)制出多個(gè)相似的對(duì)象。

使用類創(chuàng)建對(duì)象,就像自行車制造商一遍一遍地重用相同的藍(lán)圖來(lái)制造大量的自行車。

然解決重用問(wèn)題的方案,當(dāng)然不止一種。傳統(tǒng)面向?qū)ο蟮念悾皇瞧渲械囊环N方案。下面輪到我們的主角“原型繼承”登場(chǎng)了,它從另一個(gè)角度解決了重用的問(wèn)題。

原型繼承的原理 原型對(duì)象

javaScript 中的 object 由兩部分組成,普通屬性的集合,和原型屬性。

var o = { a : ’a’, ... __proto__: prototypeObj}

普通屬性指的就是 a ; 原型屬性 指的是 __proto__ 。這本不屬于規(guī)范的一部分,后來(lái) chrome 通過(guò) __proto__ 將這個(gè)語(yǔ)言底層屬性給暴露出來(lái)了,慢慢的被大家所接受,也就添加到 ES6 規(guī)范中了。 o.__proto__ 的值 prototypeObj 也就是 原型對(duì)象 。原型對(duì)象其實(shí)也就是一個(gè)普通對(duì)象,之所以叫原型對(duì)象的原因,只是因?yàn)樗窃蛯傩运傅闹怠?/p>

原型對(duì)象所以特殊,是因?yàn)樗鼡碛幸粋€(gè)普通對(duì)象沒(méi)有的能力:將它的屬性共享給其他對(duì)象。

在 ES6 規(guī)范 中,對(duì)它是如下定義的:

object that provides shared properties for other objects 屬性讀操作

回到最開始的例子,看看如何利用原型繼承實(shí)現(xiàn)重用的目的。

var prototypeObj = { hello: function(){ console.log( ’Hello, my name is ’+ this.name + ’.’); } // ...}var xiaoMing = { name : 'xiaoMing', __proto__ : prototypeObj}var liLei = { name : 'liLei', __proto__ : prototypeObj}xiaoMing.hello(); // Hello, my name is xiaoMing.liLei.hello(); // Hello, my name is liLei.

xiaoMing liLei 對(duì)象上,并沒(méi)直接擁有 hello 屬性(方法),但是卻能讀取該屬性(執(zhí)行該方法),這是為什么?

想象一個(gè)場(chǎng)景,你在做數(shù)學(xué)作業(yè),遇到一個(gè)很難的題目,你不會(huì)做。而你有一個(gè)好兄弟,數(shù)學(xué)很厲害,你去請(qǐng)教他,把這道題做出來(lái)了。

xiaoMing 對(duì)象上,沒(méi)有 hello 屬性,但是它有一個(gè)好兄弟, prototypeObj 。屬性讀操作,在 xiaoMing 身上沒(méi)有找到 hello 屬性,就會(huì)去問(wèn)它的兄弟 prototypeObj 。所以 hello 方法會(huì)被執(zhí)行。

原型鏈

還是做數(shù)學(xué)題的例子。你的數(shù)學(xué)題目很難,你的兄弟也沒(méi)有答案,他推薦你去問(wèn)另外一個(gè)同學(xué)。這樣直到有了答案或者再也沒(méi)有人可以問(wèn),你就不會(huì)再問(wèn)下去。這樣就好像有一條無(wú)形鏈條把你和同學(xué)們牽在了一起。

在 JS 中,讀操作通過(guò) __proto__ 會(huì)一層一層鏈下去的結(jié)構(gòu),就叫 原型鏈 。

var deepPrototypeObj = { hello: function(){ console.log( ’Hello, my name is ’+ this.name + ’.’); } __proto__ : null}var prototypeObj = { __proto__ : deepPrototypeObj}var xiaoMing = { name : 'xiaoMing', __proto__ : prototypeObj}var liLei = { name : 'liLei', __proto__ : prototypeObj}xiaoMing.hello(); // Hello, my name is xiaoMing.liLei.hello(); // Hello, my name is liLei. 原型繼承的實(shí)現(xiàn)

在上面的例子中,通過(guò)直接修改了 __proto__ 屬性值,實(shí)現(xiàn)了原型繼承。但是在實(shí)際生產(chǎn)中,

代替的方式是使用 Object.create() 方法。

調(diào)用 Object.create() 方法會(huì)創(chuàng)建一個(gè)新對(duì)象,同時(shí)指定該對(duì)象的原型對(duì)象為傳入的第一個(gè)參數(shù)。

我們將上面的例子改一下。

var prototypeObj = { hello: function(){ console.log( ’Hello, my name is ’+ this.name + ’.’); } // ...}var xiaoMing = Object.create(prototypeObj);var liLei = Object.create(prototypeObj);xiaoMing.name = 'xiaoMing';liLei.name = 'liLei';xiaoMing.hello(); // Hello, my name is xiaoMing.liLei.hello(); // Hello, my name is liLei.

You-Dont-Know-JS 的作者,對(duì)這種原型繼承的實(shí)現(xiàn)取了一個(gè)很好玩的名字 OLOO (objects-linked-to-other-objects) ,這種實(shí)現(xiàn)方式的優(yōu)點(diǎn)是沒(méi)有使用任何類的概念,只有 object ,所以它是很符合 javaScript 的特性的。

因?yàn)镴S 中本無(wú)類,只有 object 。

無(wú)奈的是,喜歡類的程序員是在太多,所以在 ES6 新增了 class 概念。下一篇會(huì)講 class 在 JS 中的實(shí)現(xiàn)原理

小結(jié)

類創(chuàng)建對(duì)象,達(dá)到了重用的目的。它基于的邏輯是,兩個(gè)或多個(gè)對(duì)象的結(jié)構(gòu)功能類似,可以抽象出一個(gè)模板,依照模板 復(fù)制 出多個(gè)相似的對(duì)象。就像自行車制造商一遍一遍地重用相同的藍(lán)圖來(lái)制造大量的自行車。

使用原型繼承,同樣可以達(dá)到重用的目的。它基于的邏輯是,兩個(gè)或多個(gè)對(duì)象的對(duì)象有一部分共用屬性,可以將共用的屬性抽象到另一個(gè)獨(dú)立公共對(duì)象上,通過(guò)特殊的原型屬性,將公共對(duì)象和普通對(duì)象鏈接起來(lái),再利用屬性讀(寫)規(guī)則進(jìn)行遍歷查找,實(shí)現(xiàn)屬性 共享 。

來(lái)自:https://segmentfault.com/a/1190000008293372

標(biāo)簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 欧美日产国产亚洲综合图区一 | 精品欧美一区二区三区在线 | 在线观看国产精品入口 | 亚洲欧美在线视频 | 女人张开腿给男人捅 | 日本人视频网站一 | 日本免费毛片在线高清看 | 欧美日韩一区二区三区在线 | 国产精品99r8免费视频2022 | 日韩精品视频免费在线观看 | 亚洲国产一区二区三区在线观看 | 免费人成黄页在线观看视频国产 | 国产成人免费午夜性视频 | 性夜黄a爽爽免费视频国产 性夜影院爽黄a爽免费看网站 | 欧美成人看片一区二区三区尤物 | 成人免费毛片一区二区三区 | 91国内精品久久久久影院优播 | 99精品国产成人一区二区在线 | 国产成人精品午夜视频' | 亚洲精品高清在线观看 | japanesetubesexfree | 日本加勒比在线观看 | 色综合91久久精品中文字幕 | 亚洲一级毛片视频 | 亚洲乱人伦精品图片 | 欧美一区二区三区在线观看免费 | 免费一区二区三区久久 | 欧美的高清视频在线观看 | 亚洲成人黄色在线 | 久久国产精品永久免费网站 | 日韩精品在线播放 | 日韩一区二区不卡中文字幕 | 国产成人精品三区 | 久久亚洲高清观看 | 美女毛片大全 | 亚洲精品不卡午夜精品 | 在线视频 国产交换 | 久热香蕉在线视频 | 国产成人美女福利在线观看 | 麻豆国产96在线 | 中国 | 99热久久精品免费精品 |