JavaScript原型與原型鏈深入探究使用方法
原型(prototype)
每一個(gè)函數(shù)都有一個(gè) prototype 屬性,它默認(rèn)指向一個(gè)Object空對(duì)象(即稱為:原型對(duì)象)。
<script>
console.log(Date.prototype, typeof Date.prototype);
function fun(){
}
fun.prototype.test = function(){ //給原型對(duì)象添加一個(gè)方法
console.log('test()');
}
console.log(fun.prototype); // 默認(rèn)指向一個(gè)Object空對(duì)象(沒(méi)有我們的屬性)
</script>
原型對(duì)象中有一個(gè)屬性 constructor ,它指向函數(shù)對(duì)象。
<script>
function fun(){
}
console.log(Date.prototype.constructor === Date);
console.log(fun.prototype.constructor === fun);
</script>
給原型對(duì)象添加屬性(一般是方法) ===> 實(shí)例對(duì)象可以訪問(wèn)。
有的時(shí)候我們想要在所有已經(jīng)存在的對(duì)象添加新的屬性或方法。
另外,有時(shí)候我們想要在對(duì)象的構(gòu)造函數(shù)中添加屬性或方法。
使用 prototype 屬性就可以給對(duì)象的構(gòu)造函數(shù)添加新的屬性:
<script>
function fun(){
}
fun.prototype.test = function(){//給原型對(duì)象添加方法(屬性)
console.log('test()');
}
var fn = new fun()//函數(shù)的所有實(shí)例對(duì)象自動(dòng)擁有原型中的方法(屬性)
fn.test()
</script>
顯示原型與隱式原型
每一個(gè)函數(shù) function 都有一個(gè) prototype,即顯示原型。默認(rèn)指向一個(gè)空的 Object 對(duì)象。
<script>
function fun(){
}
console.log(fun.prototype);
</script>
每個(gè)實(shí)例對(duì)象都有一個(gè) __proto__ ,可稱為隱式原型。
<script>
function fun(){
}
var fn = new fun()
console.log(fn.__proto__);
</script>
對(duì)象的隱式原型的值 為其對(duì)應(yīng) 構(gòu)造函數(shù)的顯示原型的值。
<script>
function fun(){
}
// console.log(fun.prototype);
var fn = new fun()
// console.log(fn.__proto__);
console.log(fun.prototype === fn.__proto__); //結(jié)果是 true
</script>總結(jié):
函數(shù)的 prototype 屬性:在定義函數(shù)時(shí)自動(dòng)添加的,默認(rèn)值是一個(gè)空的 Object 對(duì)象。
對(duì)象的 __proto__ 屬性:創(chuàng)建對(duì)象時(shí)自動(dòng)添加的,默認(rèn)值為構(gòu)造函數(shù)的 prototype 屬性值。
程序員能直接操作顯示原型,但不能直接操作隱式原型(ES6之前)。
原型鏈
原型鏈(本質(zhì)為:隱式原型鏈,作用:查找對(duì)象的屬性或方法),訪問(wèn)一個(gè)對(duì)象的屬性時(shí),先在自身屬性中查找,找到返回;如果沒(méi)有,再沿著 __proto__ 這條鏈向上查找,找到返回;如果最終沒(méi)找到,返回 undefined。
<script>
console.log(Object.prototype.__proto__);
function Fun(){
this.test1 = function(){
console.log('test1()');
}
}
console.log(Fun.prototype);
Fun.prototype.test2 = function(){
console.log('test2()');
}
var fun = new Fun()
fun.test1()
fun.test2()
console.log(fun.toString())
fun.test3()
</script>

總結(jié):
JavaScript 對(duì)象有一個(gè)指向一個(gè)原型對(duì)象的鏈。當(dāng)試圖訪問(wèn)一個(gè)對(duì)象的屬性時(shí),它不僅僅在該對(duì)象上搜尋,還會(huì)搜尋該對(duì)象的原型,以及該對(duì)象的原型的原型,依次層層向上搜索,直到找到一個(gè)名字匹配的屬性或到達(dá)原型鏈的末尾。
<script>
function Fun(){
}
//函數(shù)的顯示原型指向的對(duì)象默認(rèn)是空 Object 實(shí)例對(duì)象(但 Object 不滿足)
console.log(Fun.prototype instanceof Object);
console.log(Object.prototype instanceof Object);
console.log(Function.prototype instanceof Object);
//所有函數(shù)都是 Function 的實(shí)例(包括 Function)
console.log(Function.__proto__ === Function.prototype);
// Object 的原型對(duì)象是原型鏈的盡頭
console.log(Object.prototype.__proto__);
</script>
原型鏈屬性問(wèn)題
讀取對(duì)象的屬性值時(shí):會(huì)自動(dòng)查找到原型鏈中查找;設(shè)置對(duì)象屬性時(shí):不會(huì)查找原型鏈,如果當(dāng)前對(duì)象中沒(méi)有此屬性,直接添加此屬性值并設(shè)置其值;方法一般定義在原型中,屬性一般通過(guò)構(gòu)造函數(shù)定義在對(duì)象本身上。
<script>
function Fun(){
}
Fun.prototype.a = 'xxx'
var fun = new Fun()
console.log(fun.a,fun);
var fun1 = new Fun()
fun1.a = 'yyy'
console.log(fun.a,fun1.a,fun1);
function Person(name,age){
this.name = name
this.age = age
}
Person.prototype.setName = function(name){
this.name = name
}
var p1 = new Person('Tom',12)
p1.setName('Bob')
console.log(p1);
var p2 = new Person('Jack',12)
p2.setName('andy')
console.log(p2);
console.log(p1.__proto__ === p2.__proto__);
</script>
原型鏈 instanceof 使用
表達(dá)式:A instanceof B ;如果B函數(shù)的顯示原型對(duì)象在A對(duì)象的原型鏈中,返回true,否則返回false;Function是通過(guò)new自己產(chǎn)生的實(shí)例。
<script>
function Fun(){}
var fn = new Fun()
console.log(fn instanceof Fun);
console.log(fn instanceof Object);
console.log(Object instanceof Function);
console.log(Object instanceof Object);
console.log(Function instanceof Function);
console.log(Function instanceof Object);
function Foo(){}
console.log(Object instanceof Foo);
</script>
練習(xí)
<script>
function A(){}
A.prototype.n = 1
var b = new A()
A.prototype = {
n:2,
m:3
}
var c = new A()
console.log(b.n, b.m, c.n, c.m);
</script>
其實(shí)現(xiàn)原理如下圖所示(圖有點(diǎn)草,湊合看吧哈哈)

<script>
function F(){}
Object.prototype.a = function(){
console.log('a()');
}
Function.prototype.b = function(){
console.log('b()');
}
var f = new F()
f.a()
F.a()
F.b()
console.log(f);
console.log(Object.prototype);
console.log(Function.prototype);
</script>
到此這篇關(guān)于JavaScript原型與原型鏈深入探究使用方法的文章就介紹到這了,更多相關(guān)JS原型與原型鏈內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序web-view不支持打開非業(yè)務(wù)域名https?//XXXX?請(qǐng)重新配置的解決辦法
小程序現(xiàn)在日漸成熟,功能也越來(lái)越強(qiáng)大,我們今天來(lái)一起看看小程序跳轉(zhuǎn)H5頁(yè)面的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于微信小程序web-view不支持打開非業(yè)務(wù)域名https?//XXXX?請(qǐng)重新配置的解決辦法,需要的朋友可以參考下2022-08-08
解析JavaScript中delete操作符不能刪除的對(duì)象
這篇文章主要是對(duì)JavaScript中delete操作符不能刪除的對(duì)象進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
AlertBox 彈出層信息提示框效果實(shí)現(xiàn)步驟
彈出層就是相對(duì)文檔或窗口定位的一個(gè)層,一般用來(lái)顯示提示信息、廣告等內(nèi)容,還可以配合覆蓋層來(lái)鎖定頁(yè)面。2010-10-10
微信小程序?qū)崿F(xiàn)頁(yè)面下拉刷新和上拉加載功能詳解
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)頁(yè)面下拉刷新和上拉加載功能,結(jié)合實(shí)例形式分析了微信小程序頁(yè)面下拉刷新和上拉加載相關(guān)事件監(jiān)聽與功能實(shí)現(xiàn)操作技巧,需要的朋友可以參考下2018-12-12
js實(shí)現(xiàn)列表自動(dòng)滾動(dòng)循環(huán)播放
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)列表自動(dòng)滾動(dòng)循環(huán)播放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
有趣的JavaScript數(shù)組長(zhǎng)度問(wèn)題代碼說(shuō)明
有趣的JavaScript數(shù)組代碼示例,學(xué)習(xí)js的朋友可以參考下。注意以下的情況。2011-01-01

