您好,登錄后才能下訂單哦!
這篇文章給大家介紹JavaScript的原型及原型鏈的用法,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
JavaScript 是世界上最流行的腳本語(yǔ)言。 JavaScript 是屬于 web 的語(yǔ)言,它適用于 PC、筆記本電腦、平板電腦和移動(dòng)電話。 JavaScript 被設(shè)計(jì)為向 HTML 頁(yè)面增加交互性。 許多 HTML 開發(fā)者都不是程序員,但是 JavaScript 卻擁有非常簡(jiǎn)單的語(yǔ)法。幾乎每個(gè)人都有能力將小的 JavaScript 片段添加到網(wǎng)頁(yè)中。
原型
原型的出現(xiàn),就是為了解決 構(gòu)造函數(shù)的缺點(diǎn)也就是給我們提供了一個(gè)給對(duì)象添加函數(shù)的方法不然構(gòu)造函數(shù)只能給對(duì)象添加屬性,不能合理的添加函數(shù)就太 LOW 了
prototype
每一個(gè)函數(shù)天生自帶一個(gè)成員,叫做 prototype,是一個(gè)對(duì)象空間即然每一個(gè)函數(shù)都有,構(gòu)造函數(shù)也是函數(shù),構(gòu)造函數(shù)也有這個(gè)對(duì)象空間這個(gè) prototype 對(duì)象空間可以由函數(shù)名來(lái)訪問(wèn)
function Person() {}
console.log(Person.prototype) // 是一個(gè)對(duì)象
即然是個(gè)對(duì)象,那么我們就可以向里面放入一些東西
function Person() {}
Person.prototype.name = 'prototype'
Person.prototype.sayHi = function () {}
我們發(fā)現(xiàn)了一個(gè)叫做 prototype 的空間是和函數(shù)有關(guān)聯(lián)的并且可以向里面存儲(chǔ)一些東西重點(diǎn): 在函數(shù)的 prototype 里面存儲(chǔ)的內(nèi)容,不是給函數(shù)使用的,是給函數(shù)的每一個(gè)實(shí)例化對(duì)象使用的那實(shí)例化對(duì)象怎么使用能?
__proto__
每一個(gè)對(duì)象都天生自帶一個(gè)成員,叫做 __proto__,是一個(gè)對(duì)象空間即然每一個(gè)對(duì)象都有,實(shí)例化對(duì)象也是對(duì)象,那么每一個(gè)實(shí)例化對(duì)象也有這個(gè)成員這個(gè) __proto__ 對(duì)象空間是給每一個(gè)對(duì)象使用的當(dāng)你訪問(wèn)一個(gè)對(duì)象中的成員的時(shí)候
如果這個(gè)對(duì)象自己本身有這個(gè)成員,那么就會(huì)直接給你結(jié)果如果沒有,就會(huì)去 __proto__ 這個(gè)對(duì)象空間里面找,里面有的話就給你結(jié)果未完待續(xù)。。。
那么這個(gè) __proto__ 又指向哪里呢?
這個(gè)對(duì)象是由哪個(gè)構(gòu)造函數(shù) new 出來(lái)的那么這個(gè)對(duì)象的 __proto__ 就指向這個(gè)構(gòu)造函數(shù)的 prototype
function Person() {}
var p1 = new Person()
console.log(p1.__proto__ === Person.prototype) // true
我們發(fā)現(xiàn)實(shí)例化對(duì)象的 __proto__ 和所屬的構(gòu)造函數(shù)的 prototype 是一個(gè)對(duì)象空間我們可以通過(guò)構(gòu)造函數(shù)名稱來(lái)向 prototype 中添加成員對(duì)象在訪問(wèn)的時(shí)候自己沒有,可以自動(dòng)去自己的 __proto__ 中查找那么,我們之前構(gòu)造函數(shù)的缺點(diǎn)就可以解決了
我們可以把函數(shù)放在構(gòu)造函數(shù)的 prototype 中實(shí)例化對(duì)象訪問(wèn)的時(shí)候,自己沒有,就會(huì)自動(dòng)去 __proto__ 中找那么也可以使用了
function Person() {}
Person.prototype.sayHi = function () {
console.log('hello Person')
}
var p1 = new Person()
p1.sayHi()
p1 自己沒有 sayHi 方法,就會(huì)去自己的 __proto__ 中查找p1.__proto__ 就是 Person.prototype我們又向 Person.prototype 中添加了 sayHi 方法所以 p1.sayHi 就可以執(zhí)行了
到這里,當(dāng)我們實(shí)例化多個(gè)對(duì)象的時(shí)候,每個(gè)對(duì)象里面都沒有方法
都是去所屬的構(gòu)造函數(shù)的 protottype 中查找那么每一個(gè)對(duì)象使用的函數(shù),其實(shí)都是同一個(gè)函數(shù)那么就解決了我們構(gòu)造函數(shù)的缺點(diǎn)
function Person() {}
Person.prototype.sayHi = function () {
console.log('hello')
}
var p1 = new Person()
var p2 = new Person()
console.log(p1.sayHi === p2.sayHi)
p1 是 Person 的一個(gè)實(shí)例p2 是 Person 的一個(gè)實(shí)例也就是說(shuō) p1.__proto__ 和 p2.__proto__ 指向的都是 Person.prototype當(dāng) p1 去調(diào)用 sayHi 方法的時(shí)候是去 Person.prototype 中找當(dāng) p2 去調(diào)用 sayHi 方法的時(shí)候是去 Person.prototype 中找那么兩個(gè)實(shí)例化對(duì)象就是找到的一個(gè)方法,也是執(zhí)行的一個(gè)方法
結(jié)論
當(dāng)我們寫構(gòu)造函數(shù)的時(shí)候?qū)傩晕覀冎苯訉懺跇?gòu)造函數(shù)體內(nèi)方法我們寫在原型上
插個(gè)小消息,也方便想學(xué)習(xí)入行成為程序員的同學(xué),在文章下方留言即可試聽課程外加領(lǐng)取千鋒HTML5、UI交互設(shè)計(jì)、PHP、Java+云數(shù)據(jù)、大數(shù)據(jù)開發(fā)、VR/AR/Unity游戲開發(fā)、Python人工智能、Linux云計(jì)算、全棧軟件測(cè)試、網(wǎng)絡(luò)安全等全部的視頻學(xué)習(xí)教程。
原型鏈
我們剛才聊過(guò)構(gòu)造函數(shù)了,也聊了原型那么問(wèn)題出現(xiàn)了,我們說(shuō)構(gòu)造函數(shù)的 prototype 是一個(gè)對(duì)象又說(shuō)了每一個(gè)對(duì)象都天生自帶一個(gè) __proto__ 屬性那么 構(gòu)造函數(shù)的 prototype 里面的 __proto__ 屬性又指向哪里呢?
一個(gè)對(duì)象所屬的構(gòu)造函數(shù)
每一個(gè)對(duì)象都有一個(gè)自己所屬的構(gòu)造函數(shù)比如: 數(shù)組
// 數(shù)組本身也是一個(gè)對(duì)象
var arr = []
var arr2 = new Array()
以上兩種方式都是創(chuàng)造一個(gè)數(shù)組我們就說(shuō)數(shù)組所屬的構(gòu)造函數(shù)就是 Array
比如: 函數(shù)
// 函數(shù)本身也是一個(gè)對(duì)象
var fn = function () {}
var fun = new Function()
以上兩種方式都是創(chuàng)造一個(gè)函數(shù)我們就說(shuō)函數(shù)所屬的構(gòu)造函數(shù)就是 Function
constructor
對(duì)象的 __proto__ 里面也有一個(gè)成員叫做 constructor這個(gè)屬性就是指向當(dāng)前這個(gè)對(duì)象所屬的構(gòu)造函數(shù)
鏈狀結(jié)構(gòu)
當(dāng)一個(gè)對(duì)象我們不知道準(zhǔn)確的是誰(shuí)構(gòu)造的時(shí)候,我們呢就把它看成 Object 的實(shí)例化對(duì)象也就是說(shuō),我們的 構(gòu)造函數(shù) 的 prototype 的 __proto__ 指向的是 Object.prototype那么 Object.prototype 也是個(gè)對(duì)象,那么它的 __proto__ 又指向誰(shuí)呢?因?yàn)?Object 的 js 中的頂級(jí)構(gòu)造函數(shù),我們有一句話叫 萬(wàn)物皆對(duì)象所以 Object.prototype 就到頂了,Object.prototype 的 __proto__ 就是 null
原型鏈的訪問(wèn)原則
我們之前說(shuō)過(guò),訪問(wèn)一個(gè)對(duì)象的成員的時(shí)候,自己沒有就會(huì)去 __proto__ 中找接下來(lái)就是,如果 __proto__ 里面沒有就再去 __proto__ 里面找一直找到 Object.prototype 里面都沒有,那么就會(huì)返回 undefiend
對(duì)象的賦值
到這里,我們就會(huì)覺得,如果是賦值的話,那么也會(huì)按照原型鏈的規(guī)則來(lái)但是: 并不是!并不是!并不是! 重要的事情說(shuō)三遍賦值的時(shí)候,就是直接給對(duì)象自己本身賦值
如果原先有就是修改原先沒有就是添加不會(huì)和 __proto__ 有關(guān)系
總結(jié)
到了這里,我們就發(fā)現(xiàn)了面向?qū)ο蟮乃枷肽J搅?/p>
當(dāng)我想完成一個(gè)功能的時(shí)候先看看內(nèi)置構(gòu)造函數(shù)有沒有能給我提供一個(gè)完成功能對(duì)象的能力如果沒有,我們就自己寫一個(gè)構(gòu)造函數(shù),能創(chuàng)造出一個(gè)完成功能的對(duì)象然后在用我們寫的構(gòu)造函數(shù) new 一個(gè)對(duì)象出來(lái),幫助我們完成功能就行了
比如: tab選項(xiàng)卡
我們要一個(gè)對(duì)象對(duì)象包含一個(gè)屬性:是每一個(gè)點(diǎn)擊的按鈕對(duì)象包含一個(gè)屬性:是每一個(gè)切換的盒子對(duì)象包含一個(gè)方法:是點(diǎn)擊按鈕能切換盒子的能力那么我們就需要自己寫一個(gè)構(gòu)造函數(shù),要求 new 出來(lái)的對(duì)象有這些內(nèi)容就好了然后在用構(gòu)造函數(shù) new 一個(gè)對(duì)象就行了。
關(guān)于JavaScript的原型及原型鏈的用法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。