国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

如何用原型鏈的方式實(shí)現(xiàn)一個(gè) JS 繼承?

開(kāi)發(fā) 前端
JavaScript 中,每當(dāng)創(chuàng)建一個(gè)對(duì)象,都會(huì)給這個(gè)對(duì)象提供一個(gè)內(nèi)置對(duì)象 [[Prototype]] 。這個(gè)對(duì)象就是原型對(duì)象,[[Prototype]] 的層層嵌套就形成了原型鏈。

大家好,我是前端西瓜哥。今天講一道經(jīng)典的原型鏈面試題。

原型鏈?zhǔn)鞘裁?

JavaScript 中,每當(dāng)創(chuàng)建一個(gè)對(duì)象,都會(huì)給這個(gè)對(duì)象提供一個(gè)內(nèi)置對(duì)象 [[Prototype]] 。這個(gè)對(duì)象就是原型對(duì)象,[[Prototype]] 的層層嵌套就形成了原型鏈。

當(dāng)我們?cè)L問(wèn)一個(gè)對(duì)象的屬性時(shí),如果自身沒(méi)有,就會(huì)通過(guò)原型鏈向上追溯,找到第一個(gè)存在該屬性原型對(duì)象,取出對(duì)應(yīng)值。

當(dāng)然原型鏈不是無(wú)止境的,和單鏈表一樣,最后一個(gè)原型對(duì)象的值是 null,原型鏈的所有對(duì)象都找不到指定的屬性時(shí),我們會(huì)拿到 undefined。

[[Prototype]] 雖然無(wú)法通過(guò)腳本進(jìn)行訪問(wèn),但大多數(shù)瀏覽器提供了 __proto__ 屬性來(lái)訪問(wèn)這個(gè)內(nèi)置對(duì)象,但它并不是標(biāo)準(zhǔn),無(wú)法兼容所有瀏覽器。

下面來(lái)舉幾個(gè)例子,讓讀者對(duì)原型鏈有一個(gè)直觀的認(rèn)識(shí):

  • 通過(guò)對(duì)象字面量聲明 a = {} 時(shí), a 的 [[prototype]] 就是 Object.prototype。此時(shí)的原型鏈?zhǔn)牵篴 -> Object.prototype -> null。這里有個(gè)易錯(cuò)點(diǎn),就是以為 a 的上一個(gè)原型對(duì)象是 Object,其實(shí)并不對(duì),Object 其實(shí)只是一個(gè)構(gòu)造函數(shù)。
  • 聲明數(shù)組 arr = [1, 2, 4],它的原型鏈則是 arr -> Array.prototype -> Object.prototype -> null。
  • Object.create(null) 甚至能夠創(chuàng)建一個(gè)連 [[prototype]] 都沒(méi)有的真正的空對(duì)象,一般用于做字符串哈希表,比如 vue 源碼里就能經(jīng)常看到。

通過(guò)構(gòu)造函數(shù)創(chuàng)建實(shí)例對(duì)象

在 JavaScript 中,一個(gè)函數(shù)會(huì)在 new 關(guān)鍵字的配合下成為構(gòu)造函數(shù)。也就是說(shuō),任何一個(gè)函數(shù)都可以成為構(gòu)造函數(shù)。

當(dāng)聲明一個(gè)構(gòu)造函數(shù)時(shí),它會(huì)有一個(gè)屬性名為 prototype 的對(duì)象(和 [[prototype]] 是不同的東西),這個(gè)對(duì)象就是 原型對(duì)象。這個(gè)對(duì)象的 constructor 又反過(guò)來(lái)指向構(gòu)造函數(shù)。

當(dāng)我們對(duì)使用 new 關(guān)鍵字創(chuàng)建對(duì)象,被創(chuàng)建的對(duì)象的 [[prototype]] 會(huì)指向這個(gè) prototype。

function Rect() {}
const rect = new Rect()
rect.__proto__ === Rect.prototype // true
Rect.prototype.constructor === Rect // true

只要是通過(guò) new Rect() 創(chuàng)建的對(duì)象,無(wú)論多少次,它的 [[prototype]] 都是指向 Rect.prototype。另外,Rect.prototype.prototype 指向的是 Object.prototype。

這樣,通過(guò)給構(gòu)造函數(shù)的原型對(duì)象(Rect.prototype)添加一些方法(如 Rect.prototype.draw),就能讓創(chuàng)建的多個(gè)實(shí)例對(duì)象共享同一個(gè)方法,減少內(nèi)存的使用。

用原型鏈的方式實(shí)現(xiàn)繼承

理解了構(gòu)造函數(shù)如何影響創(chuàng)建的實(shí)例的原型鏈后,我們來(lái)探討一下核心問(wèn)題,如何使用原型鏈來(lái)實(shí)現(xiàn)繼承。

假設(shè)我們有一個(gè) Shape 構(gòu)造函數(shù)(父類)和 Rect 構(gòu)造函數(shù)(子類)。代碼如下:

// 父類
function Shape() {}
Shape.prototype.draw = function() {
console.log('Shape Draw')
}
Shape.prototype.clear = function() {
console.log('Shape Clear')
}
// 子類
function Rect() {}
/**
實(shí)現(xiàn)繼承的代碼放這里
**/
Rect.prototype.draw = function() {
console.log('Rect Draw')
}

通過(guò)前面的學(xué)習(xí),我們知道,正常情況下使用 new Rect 創(chuàng)建的實(shí)例對(duì)象,它的原型鏈?zhǔn)沁@樣的:

rect -> Rect.prototype -> Object.protoype -> null

現(xiàn)在我們要實(shí)現(xiàn)的繼承,其實(shí)就是在原型鏈中間再加一個(gè)原型對(duì)象 Shape.prototype。對(duì)此我們需要對(duì) Rect.prototype 進(jìn)行特殊的處理。

方法1:Object.create

Rect.prototype = Object.create(Shape.prototype)
Rect.prototype.constructor = Rect // 選用,如果要用到 constructor

Rect.prototype.constructor = Rect // 選用,如果要用到 constructor

Object.create(proto) 是個(gè)神奇的方法,它能夠創(chuàng)建一個(gè)空對(duì)象,并設(shè)置它的 [[prototype]] 為傳入的對(duì)象。

因?yàn)槲覀儫o(wú)法通過(guò)代碼的方式給 [[prototype]] 屬性賦值,所以使用了 Object.create 方法作為替代。

因?yàn)?Rect.prototype 指向了另一個(gè)新的對(duì)象,所以把 constructor 給丟失了,可以考慮把它放回來(lái),如果你要用到的話。

缺點(diǎn)是替換掉了原來(lái)的對(duì)象。

方法2:直接修改 [[prototype]]

如果就是不想使用新對(duì)象,只想修改原對(duì)象,可以使用 廢棄 的 __proto__ 屬性,但不推薦。

不過(guò)另外還有一個(gè)方法 Object.setPrototypeOf() 可以修改對(duì)象的 [[prototype]],但因?yàn)樾阅艿膯?wèn)題,也不推薦使用。

Object.setPrototypeOf(Rect.prototype, Shape.prototype)
//
Rect.prototype.__proto__ = Shape.prototype

都不推薦使用,但確實(shí)能用。

方法3:使用父類的實(shí)例

Rect.prototype = new Shape()

形成的原型鏈為:

rect -> shape(替代掉原來(lái)的 Rect.prototype-> Shape.prototype -> Object.prototype -> null

基本能用,缺點(diǎn)是會(huì)產(chǎn)生副作用,就是執(zhí)行 new Shap() 可能會(huì)出現(xiàn)副作用,比如給創(chuàng)建的對(duì)象添加了一些屬性、發(fā)送了請(qǐng)求之類的,完全取決于構(gòu)造函數(shù)內(nèi)的代碼。

某種意義上,這個(gè)缺點(diǎn)是致命的。不推薦使用。

總結(jié)

用原型鏈的方式實(shí)現(xiàn)一個(gè) JS 繼承,其實(shí)就是希望構(gòu)造函數(shù) Son 創(chuàng)建出來(lái)的對(duì)象 son,它的原型鏈上加上父類 Parent.prototype,所以最后就是要修改 Son.prototype 的 [[prototype]]。

鑒于性能、兼容性、副作用等考慮,推薦使用方法 1,即通過(guò) Object.create(Parent.prototype) 創(chuàng)建一個(gè)指定了 [[prototype]] 的新對(duì)象,替換掉原來(lái)的 Son.prototype 指向的對(duì)象。

總結(jié)幾個(gè)核心知識(shí)點(diǎn):

  • 任何對(duì)象都有 [[prototype]] 屬性,讀寫(xiě)對(duì)象屬性發(fā)現(xiàn)當(dāng)前對(duì)象不存在時(shí),會(huì)訪問(wèn) [[prototype]] 指向的對(duì)象嘗試訪問(wèn)屬性,于是原型鏈形成了。
  • 函數(shù)創(chuàng)建時(shí),它的 prototype 屬性會(huì)拿到一個(gè)原型對(duì)象。當(dāng)函數(shù)作為構(gòu)造函數(shù),通過(guò) new 創(chuàng)建一個(gè)新對(duì)象時(shí),這個(gè)新對(duì)象的 [[prototype]] 會(huì)指向這個(gè)原型對(duì)象。
  • JS 要實(shí)現(xiàn) “類” 繼承,本質(zhì)是通過(guò)處理構(gòu)造函數(shù)的 prototype 對(duì)象來(lái)修改原型鏈。
責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2022-06-20 09:22:55

js原型鏈前端

2023-02-26 01:37:57

goORM代碼

2016-09-06 19:45:18

javascriptVue前端

2017-03-20 17:59:19

JavaScript模板引擎

2017-03-15 08:43:29

JavaScript模板引擎

2020-09-10 07:04:30

JSJavaScript 原型鏈

2019-02-27 16:00:48

JS原型原型鏈對(duì)象

2021-05-27 08:21:51

JS繼承對(duì)象

2016-11-03 08:57:02

javascriptjquerynode.js

2021-09-13 06:03:42

CSS 技巧搜索引擎

2020-10-26 08:19:53

算法隊(duì)列

2018-06-22 10:30:56

C語(yǔ)言虛擬機(jī)編譯器

2020-04-29 14:40:19

JavaScript繼承編程語(yǔ)言

2017-05-02 11:30:44

JavaScript數(shù)組惰性求值庫(kù)

2023-12-30 13:33:36

Python解析器JSON

2022-11-07 11:27:00

JS游戲開(kāi)發(fā)

2018-03-23 10:00:34

PythonTensorFlow神經(jīng)網(wǎng)絡(luò)

2022-09-13 08:01:58

短鏈服務(wù)哈希算法字符串

2011-08-31 14:48:33

JavaScript

2020-02-20 14:00:15

JavaScript原型原型鏈
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

久久看人人摘| 日韩国产精品91| 日韩国产中文字幕| 在线看视频你懂得| 久久午夜色播影院免费高清| 影音先锋成人资源网站| 免播放器亚洲| 久久av免费观看| 亚洲午夜av| 成人性生交大片免费看小说| 日韩欧美中文字幕电影| 欧美夫妻性生活xx| 精品国产一区二区三区性色av| 伊人久久男人天堂| 忘忧草在线日韩www影院| 亚洲第一偷拍网| 激情黄产视频在线免费观看| 亚洲跨种族黑人xxx| 中文日产幕无线码一区二区| 一本久久综合亚洲鲁鲁| 亚洲日日夜夜| 久久成人这里只有精品| 深夜福利一区二区三区| 日韩av综合网站| 成人www视频网站免费观看| 久久亚洲欧美国产精品乐播| av免费在线播放网站| 久久嫩草精品久久久久| 一区二区三区视频在线观看免费| 久久久亚洲高清| 99sesese| 亚洲妇熟xx妇色黄| 日产精品久久久久久久性色| 午夜精品一区二区三区电影天堂| 污污网站在线| 欧美日韩高清一区二区三区| 中文字幕一区二区三区不卡| 欧美日韩国产影片| 99精品老司机免费视频| 欧美三级资源在线| 2024最新电影免费在线观看| 精品久久久久99| 国产精品yjizz视频网| 亚洲女同精品视频| 男人天堂久久| 欧美有码在线观看| 99久久久久久中文字幕一区| 国产欧美日韩综合一区在线观看| 亚洲欧美不卡| 国产精品久久久久9999爆乳| 国产农村妇女毛片精品久久麻豆 | 激情五月婷婷综合网| 国产日本在线播放| 亚洲人成精品久久久久| 婷婷激情在线| 自拍偷拍免费精品| 久久不见久久见中文字幕免费| 亚洲综合精品一区二区| 麻豆精品久久精品色综合| 成人羞羞国产免费网站| 亚洲第一福利一区| heyzo高清中文字幕在线| 色婷婷久久一区二区| 精品一区二区三区中文字幕老牛| 欧美一级二级三级| 日本一区二区高清| 麻豆网站在线观看| 欧美福利视频在线| av成人国产| 国产成人无码一二三区视频| 欧美综合色免费| 国产精品亚洲欧美日韩一区在线| 国产成人综合精品| 久久99精品久久久久| 免费男女羞羞的视频网站中文版 | 免费av网页| 亚洲精品wwwww| 久久99国产精品视频| 亚洲最大色综合成人av| 亚洲欧洲日韩综合一区二区| 精品国产99久久久久久| 久久久久久国产精品美女| 国产精品国内免费一区二区三区| 六月婷婷在线视频| 欧美日韩国产系列| 欧美欧美黄在线二区| 日韩成人手机在线| 在线成人小视频| 欧美精选视频在线观看| 成人免费aaa| 欧美大黄免费观看| 国内精品伊人久久| 亚洲专区一区二区三区| 免费黄色av电影| 久久久精品久久| 精品一区二区免费| 91网页在线观看| 国产一区二区在线播放| 国产偷国产偷亚洲高清人白洁 | 国产精久久一区二区| 日韩精品久久一区二区三区| 性欧美大战久久久久久久久| 精品视频在线观看免费观看| 中文字幕人成一区| 在线成人免费观看| 欧美国产另类| 啦啦啦啦免费高清视频在线观看1| 天堂资源在线中文精品| 亚洲a一区二区三区| www.欧美黄色| 综合在线观看色| 日韩精品影片| 欧美精品亚洲| 天天爽夜夜爽夜夜爽精品视频| 日本成人精品| 777久久精品一区二区三区无码| 56国语精品自产拍在线观看| 亚洲91视频| 久草视频在线播放| 亲爱的老师9免费观看全集电视剧| 午夜免费啪视频观看视频| 日韩激情第一页| 久久蜜桃资源一区二区老牛| 国产福利在线| 91啪国产在线| ...av二区三区久久精品| 国产精品亚洲欧美日韩一区在线| 男人的天堂成人| 日韩毛片中文字幕| 蜜臀久久久久久久| 成人在线高清免费| 日韩欧美电影一区二区| 日韩一区二区在线播放| 天堂久久一区二区三区| 国产精品久久麻豆| 日韩欧美国产二区| 亚洲国产美女久久久久| 免费观看30秒视频久久| 超碰在线资源| 大桥未久一区二区三区| 亚洲欧美日韩精品| 国产**成人网毛片九色 | 中国av在线播放| 国产精品一区二区三区在线观| 91国模大尺度私拍在线视频| 欧美成人高清| 午夜看片在线免费| 欧美一级二级三级九九九| 精品国内片67194| 懂色中文一区二区在线播放| 99久久婷婷国产综合精品首页| 欧美日韩中文在线视频| 97在线观看视频国产| 欧美日韩亚洲系列| 久久九九免费| 精品视频一区二区三区四区五区| 人妻丰满熟妇av无码区app| 国产97在线播放| 欧美视频一区二区三区| 丝袜亚洲另类欧美| 在线观看欧美| 四虎在线观看| 青草全福视在线| 91成人在线观看国产| 欧美日韩综合不卡| 岛国精品在线观看| 青青草97国产精品麻豆| 日本在线高清| 亚洲欧美日本国产有色| 亚洲丝袜av一区| 欧美国产一区在线| 99成人在线视频| bt在线麻豆视频| 一二三四视频社区在线| 日本a级片电影一区二区| 欧美综合视频在线观看| 国产精品亚洲一区二区三区妖精| 久久精品色综合| 免费观看在线午夜影视| 日本午夜激情视频| 日韩免费视频在线观看| 欧美一区二区三区啪啪| www久久精品| 欧美三级在线| 亚洲精品伊人| av网站在线免费播放| 乱子伦视频在线看| 国产一区二区在线观看免费播放| 在线观看欧美视频| 日韩在线免费电影| 免费av网址在线| 国产精品伊人日日| 欧美激情精品在线| 日韩视频免费直播| 亚洲日本中文字幕区| 日本强好片久久久久久aaa| 国产一区不卡| 韩国理伦片久久电影网| 香蕉视频在线免费看| 无套内精的网站|