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ì)象(沒有我們的屬性) </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ì)象可以訪問。
有的時(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ì)象的屬性或方法),訪問一個(gè)對(duì)象的屬性時(shí),先在自身屬性中查找,找到返回;如果沒有,再沿著 __proto__ 這條鏈向上查找,找到返回;如果最終沒找到,返回 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)試圖訪問一個(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>
原型鏈屬性問題
讀取對(duì)象的屬性值時(shí):會(huì)自動(dòng)查找到原型鏈中查找;設(shè)置對(duì)象屬性時(shí):不會(huì)查找原型鏈,如果當(dāng)前對(duì)象中沒有此屬性,直接添加此屬性值并設(shè)置其值;方法一般定義在原型中,屬性一般通過構(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是通過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)在日漸成熟,功能也越來越強(qiáng)大,我們今天來一起看看小程序跳轉(zhuǎn)H5頁(yè)面的問題,下面這篇文章主要給大家介紹了關(guān)于微信小程序web-view不支持打開非業(yè)務(wù)域名https?//XXXX?請(qǐng)重新配置的解決辦法,需要的朋友可以參考下2022-08-08解析JavaScript中delete操作符不能刪除的對(duì)象
這篇文章主要是對(duì)JavaScript中delete操作符不能刪除的對(duì)象進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2013-12-12AlertBox 彈出層信息提示框效果實(shí)現(xiàn)步驟
彈出層就是相對(duì)文檔或窗口定位的一個(gè)層,一般用來顯示提示信息、廣告等內(nè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-12js實(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)度問題代碼說明
有趣的JavaScript數(shù)組代碼示例,學(xué)習(xí)js的朋友可以參考下。注意以下的情況。2011-01-01