最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

在JavaScript中對(duì)原型prototype全面分析

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 19:48:21
文檔

在JavaScript中對(duì)原型prototype全面分析

在JavaScript中對(duì)原型prototype全面分析:這篇文章主要介紹了JavaScript中的原型prototype完全解析,prototype可是js界"一切皆對(duì)象"論調(diào)的重要支撐,講解了__proto__屬性和原型鏈等干貨,需要的朋友可以參考下 要理解JS中的prototype, 首先必須弄清楚以下幾個(gè)概念 1. JS中所有的
推薦度:
導(dǎo)讀在JavaScript中對(duì)原型prototype全面分析:這篇文章主要介紹了JavaScript中的原型prototype完全解析,prototype可是js界"一切皆對(duì)象"論調(diào)的重要支撐,講解了__proto__屬性和原型鏈等干貨,需要的朋友可以參考下 要理解JS中的prototype, 首先必須弄清楚以下幾個(gè)概念 1. JS中所有的
這篇文章主要介紹了JavaScript中的原型prototype完全解析,prototype可是js界"一切皆對(duì)象"論調(diào)的重要支撐,講解了__proto__屬性和原型鏈等干貨,需要的朋友可以參考下

要理解JS中的prototype, 首先必須弄清楚以下幾個(gè)概念
1. JS中所有的東西都是對(duì)象

2. JS中所有的東西都由Object衍生而來(lái), 即所有東西原型鏈的終點(diǎn)指向Object.prototype

3. JS中構(gòu)造函數(shù)和實(shí)例(對(duì)象)之間的微妙關(guān)系
構(gòu)造函數(shù)通過(guò)定義prototype來(lái)約定其實(shí)例的規(guī)格, 再通過(guò) new 來(lái)構(gòu)造出實(shí)例, 他們的作用就是生產(chǎn)對(duì)象.
而構(gòu)造函數(shù)(方法)本身又是方法(Function)的實(shí)例, 因此也可以查到它的__proto__(原型鏈)

Object / function F() {} 這樣子的就是構(gòu)造函數(shù)啦, 一個(gè)是JS原生API提供的, 一個(gè)是自定義的
new Object() / new F() 這樣子的就是實(shí)例啦
實(shí)例就"只能"查看__proto__來(lái)得知自己是基于什么prototype被制造出來(lái)的,
而"不能"再重新定義實(shí)例的prototype妄想創(chuàng)造出實(shí)例的實(shí)例了.

實(shí)踐出真知, 只有自己動(dòng)手觀察/思考才能真正領(lǐng)悟:

你可能已經(jīng)暈了, 我們來(lái)分解一下。

prototype prototype輸出的格式為: 構(gòu)造函數(shù)名 原型
首先看下Object.prototype輸出了什么?
Object {} -> 前面的Object為構(gòu)造函數(shù)的名稱, 后面的那個(gè)表示原型, 這里是一個(gè){}, 即一個(gè)Object對(duì)象的實(shí)例(空對(duì)象)
那么 F {} 我們就明白是什么意思了, F 就是構(gòu)造函數(shù)的名稱, 原型也是一個(gè)空對(duì)象

我們?cè)偕钊胍稽c(diǎn), 定義下 F 的原型看看到底會(huì)發(fā)生些什么?

這樣我們就清楚的看到 i 是由 F 構(gòu)造出來(lái)的, 原型是 {a: function}, 就是原本的空對(duì)象原型新增了一個(gè) a 方法

我們?cè)贀Q一種情況, 完全覆蓋 F 的原型會(huì)怎么樣?

咦~ 為什么這里表明 i 是由 Object 構(gòu)造出來(lái)的? 不對(duì)吧!
因?yàn)槲覀兺耆珜?F 的prototype覆蓋, 其實(shí)也就是將原型指定為對(duì)象{a: function}, 但這會(huì)造成原本的constructor信息丟失, 變成了對(duì)象{a: function}指定的constructor.
那么對(duì)象{a: function}的constructor是什么呢?
因?yàn)閷?duì)象{a: function}其實(shí)就相對(duì)于

那么o的constructor當(dāng)然是 Object 啦

我們來(lái)糾正下這個(gè)錯(cuò)誤

現(xiàn)在又能得到正確的原型信息了~

原型鏈

然后來(lái)看看什么原型鏈又是個(gè)什么東西?
簡(jiǎn)單的來(lái)講和OOP中的繼承關(guān)系(鏈)是一樣的, 一層一層往上找, 直至最終的 Object.prototype

2016510172352211.jpg (560×248)

最最關(guān)鍵的是要弄清楚JS中哪些東西是(實(shí)例)對(duì)象, 這個(gè)簡(jiǎn)單了, JS中所有東西都是對(duì)象!
再要弄清楚就是任何一個(gè)對(duì)象都是有一個(gè)原型的!

那么我們來(lái)證明一下:

Prototype和__proto__每一個(gè)對(duì)象都包含一個(gè)__proto__,指向這個(gè)的對(duì)象的“原型”。
類似的事情是,每一個(gè)函數(shù)都包含一個(gè)prototype,這個(gè)prototype對(duì)象干什么的了?

咱們看看如下代碼,用構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)對(duì)象(上面是用字面量的形式創(chuàng)建對(duì)象)。

試想想,這個(gè)foo對(duì)象的__proto__會(huì)指向什么?

2016510172448163.png (163×68)

一個(gè)包含constructor屬性的對(duì)象?看不太懂沒(méi)關(guān)系,把函數(shù)Foo的prototype屬性打印出來(lái),對(duì)比一下就知道了。

2016510172512274.png (183×69)

原來(lái),new出來(lái)的對(duì)象foo的__proto__就只指向函數(shù)Foo的prototype。

JS這么設(shè)計(jì)有何意義了?回憶下上面說(shuō)的,在JS的世界中,對(duì)象不是根據(jù)類(模具)創(chuàng)建出來(lái)的,而是從原型(另一個(gè)對(duì)象)衍生出來(lái)的。

當(dāng)我們執(zhí)行new操作創(chuàng)建一個(gè)新的對(duì)象時(shí),先不深入new操作的具體實(shí)現(xiàn),但有一點(diǎn)我們是肯定的——就是為新對(duì)象的__proto__指向一個(gè)原型對(duì)象。

就剛才這段代碼

foo.__proto__到底要指向誰(shuí)了?你怎么不能指向Foo這個(gè)函數(shù)本身吧,雖然函數(shù)也是對(duì)象,這個(gè)有機(jī)會(huì)會(huì)詳細(xì)講。但如何foo.__proto__指向Foo固然不合適,因?yàn)镕oo是一個(gè)函數(shù),有很多邏輯代碼,foo作為一個(gè)對(duì)象,繼承邏輯處理沒(méi)有任何意義,它要繼承的是“原型對(duì)象”的屬性。

所以,每個(gè)函數(shù)會(huì)自動(dòng)生成一個(gè)prototype對(duì)象,由這個(gè)函數(shù)new出來(lái)的對(duì)象的__proto__就指向這個(gè)函數(shù)的prototype。

總結(jié)說(shuō)了這么多,感覺(jué)還是沒(méi)完全說(shuō)清楚,不如上一張圖。我曾經(jīng)參考過(guò)其他網(wǎng)友的圖,但總覺(jué)得哪里沒(méi)說(shuō)清楚,所以我自己畫了一張圖,如果覺(jué)得我的不錯(cuò),請(qǐng)點(diǎn)個(gè)贊?。ɡ献涌墒琴M(fèi)了牛勁才畫出來(lái))。

2016510172555695.png (800×600)

咱們就著這張圖,記住如下幾個(gè)事實(shí):

1. 每個(gè)對(duì)象中都有一個(gè)_proto_屬性。

JS世界中沒(méi)有類(模具)的概念,對(duì)象是從另一個(gè)對(duì)象(原型)衍生出來(lái)的,所以每個(gè)對(duì)象中會(huì)有一個(gè)_proto_屬性指向它的原型對(duì)象。(參考左上角的那個(gè)用字面量形式定義的對(duì)象obj,它在內(nèi)存中開辟了一個(gè)空間存放對(duì)象自身的屬性,同時(shí)生成一個(gè)_proto_指向它的原型——頂層原型對(duì)象。)

2. 每個(gè)函數(shù)都有一個(gè)prototype屬性。

“構(gòu)造函數(shù)”為何叫構(gòu)造函數(shù),因?yàn)樗獦?gòu)造對(duì)象。那么根據(jù)上面第一條事實(shí),構(gòu)造出來(lái)的新對(duì)象的_proto_屬性指向誰(shuí)了?總不能指向構(gòu)造函數(shù)自身,雖然它也是個(gè)對(duì)象,但你不希望新對(duì)象繼承函數(shù)的屬性與方法吧。所以,在每個(gè)構(gòu)造函數(shù)都會(huì)有一個(gè)prototype屬性,指向一個(gè)對(duì)象作為這個(gè)構(gòu)造函數(shù)構(gòu)造出來(lái)的新對(duì)象的原型。

3. 函數(shù)也是對(duì)象。

每個(gè)函數(shù)都有一些通用的屬性和方法,比如apply()/call()等。但這些通用的方法是如何繼承的呢?函數(shù)又是怎么創(chuàng)建出來(lái)的呢?試想想,一切皆對(duì)象,包括函數(shù)也是對(duì)象,而且是通過(guò)構(gòu)造函數(shù)構(gòu)造出來(lái)的對(duì)象。那么根據(jù)上面第二條事實(shí),每個(gè)函數(shù)也會(huì)有_proto_指向它的構(gòu)造函數(shù)的prototype。而這個(gè)構(gòu)造函數(shù)的函數(shù)就是Function,JS中的所有函數(shù)都是由Function構(gòu)造出來(lái)的。函數(shù)的通用屬性與方法就存放在Function.prototype這個(gè)原型對(duì)象上。

上面是我整理給大家的,希望今后會(huì)對(duì)大家有幫助。

相關(guān)文章:

全面分析JavaScript面向?qū)ο蟾拍钪械腛bject類型與作用域(附有示例)

在javascript中創(chuàng)建對(duì)象的各種模式解析(圖文教程)

詳細(xì)解讀JavaScript設(shè)計(jì)模式開發(fā)中的橋接模式(高級(jí)篇)

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

在JavaScript中對(duì)原型prototype全面分析

在JavaScript中對(duì)原型prototype全面分析:這篇文章主要介紹了JavaScript中的原型prototype完全解析,prototype可是js界"一切皆對(duì)象"論調(diào)的重要支撐,講解了__proto__屬性和原型鏈等干貨,需要的朋友可以參考下 要理解JS中的prototype, 首先必須弄清楚以下幾個(gè)概念 1. JS中所有的
推薦度:
標(biāo)簽: js 全面 解析
  • 熱門焦點(diǎn)

最新推薦

猜你喜歡

熱門推薦

專題
Top