摘要:只是構(gòu)造函數(shù)上的一個屬性,它是一個指針,指向原型對象,并不表示就是原型對象。在上一個例子中,就是一個對象,這個對象可以說是原生構(gòu)造函數(shù)的實例,所以也是一個對象,所以它也有屬性,不過它的指向也就是原型鏈的頂端,再往上就沒有了。
上一篇講了
①原型對象是什么;
②__proto__、prototype、constructor的關(guān)系;
③原型對象的作用;
④原型對象帶來的一些需要注意的問題;
沒理解的可以再復(fù)習(xí)一下。
傳送門:JS基礎(chǔ)—原型對象的那些事(一)
今天講一下原型鏈以及原型鏈的關(guān)系圖。
原型鏈是什么每個對象都有一個__proto__屬性,指向?qū)ο蟮脑汀?/p>
ps:準確的說,是每一個實例都有一個[[Prototype]]屬性,指向原型對象。這是一個隱式屬性,存在但是我們的腳本訪問不到,不過瀏覽器廠商大部分都支持一個__proto__屬性,用來顯示指向原型,雖然能用,但__proto__不是ECMA中的規(guī)范。
原型的值可以是一個對象,也可以是null。如果它的值是一個對象,那么這個對象也一定有自己的原型。這樣就形成了一條線性的鏈,我們稱之為原型鏈。
當我們在對象上調(diào)用一個屬性或者方法時,會先在這個對象上尋找,沒有的話就去它的原型對象上找,原型對象上沒有就去原型對象的原型對象上找,一直找到原型對象為null為止,沒有的話就是undefined。
簡而言之,對象尋找一個屬性會沿著原型鏈向上尋找,直到原型鏈的頂端。
還是以上一篇的Person為例
function Person(name) { this.name = name } Person.prototype.sayName = function() { console.log(this.name) } var person = new Person("張三")
我們先來畫一個簡單的關(guān)于原型的關(guān)系圖
以上是實例、構(gòu)造函數(shù)和原型對象三者的關(guān)系圖。
PS: prototype只是構(gòu)造函數(shù)上的一個屬性,它是一個指針,指向原型對象,并不表示Person.prototype就是原型對象。這里將Person.prototype認為是原型對象,是為了方便理解,需要注意哦。
看不懂的同學(xué)去復(fù)習(xí)上一篇的內(nèi)容,看懂的我們繼續(xù)。
注意點一原型對象也是對象,是對象就有__proto__屬性,指向它的原型對象。
在上一個例子中,Person.prototype就是一個對象,這個對象可以說是原生Object構(gòu)造函數(shù)的實例,所以
Person.prototype.__proto__ === Object.prototype
Object.prototype也是一個對象,所以它也有__proto__屬性,不過它的__proto__指向null,也就是原型鏈的頂端,再往上就沒有了。
重新補充一下關(guān)系圖
看懂的我們繼續(xù)
注意點二任何函數(shù)都可以說是原生Function構(gòu)造函數(shù)的實例。
所以Person構(gòu)造函數(shù)是Function構(gòu)造函數(shù)的實例。
Person.__proto__ === Function.prototype
繼續(xù)我完善我們的關(guān)系圖
可能有人疑惑,Person不是函數(shù)嗎,函數(shù)怎么也有__proto__,函數(shù)不是只有prototype嗎?
因為函數(shù)本質(zhì)也是對象啊,在JS的世界里,萬物皆對象,所以函數(shù)有__proto__沒毛病。
注意點三Function.prototype也是對象,所以和Person.prototype一樣,Function.prototype可以說是原生Object構(gòu)造函數(shù)的實例,所以
Function.prototype.__proto__ === Object.prototype
補充我們的圖(紅色的線)
注意點四Function和Object都是構(gòu)造函數(shù),根據(jù)第二點任何函數(shù)都可以說是原生Function構(gòu)造函數(shù)的實例,那么
Function.__proto__ === Function.prototype Object.__proto__ === Function.prototype
完善我們的圖(藍色的線),大功告成。
恩,就是這么神奇,Function是Function的實例。。。
以上就是原型鏈的關(guān)系圖,將這個圖弄懂,原型對象的知識基本就掌握了。
雖然在真實場景中,這些知識用到的沒這么復(fù)雜,但是掌握了最基礎(chǔ)的知識,將來出現(xiàn)問題時,就能更快的找到問題的原因。
對于新手而言,原型鏈和作用域鏈經(jīng)常搞混,this和靜態(tài)作用域不知道在場景中怎么使用,確實是很頭疼的問題,但這也許就是js的魅力所在吧。有時間的話再寫一下作用域的知識~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88486.html
摘要:通過同一個構(gòu)造函數(shù)實例化的多個實例對象具有同一個原型對象。所以當給原型對象賦值一個新對象時,切記將原型對象的指回原構(gòu)造函數(shù)以上就是本次分享的內(nèi)容,關(guān)于原型對象的其他知識,下一篇基礎(chǔ)原型對象的那些事二會講到。 談起js的基礎(chǔ),繞不過去的坎就是:原型鏈、作用域鏈、this(em...好吧,還有閉包),今天總結(jié)一下關(guān)于原型對象的一些知識,供自己和大家復(fù)習(xí)。 概念理解 什么是原型對象呢?有以下...
摘要:委托上面的代碼結(jié)合了構(gòu)造函數(shù)和原型兩種方式去創(chuàng)建對象,首先聊聊構(gòu)造函數(shù)構(gòu)造函數(shù)構(gòu)造函數(shù)本質(zhì)上還是函數(shù),只不過為了區(qū)分將其首字母大寫了而已。注意注釋掉的代碼是自動執(zhí)行的,但這并不是構(gòu)造函數(shù)獨有的,每個函數(shù)在聲明時都會自動生成。 首先看看下面兩個1+1=2的問題: 問題一:為什么改變length的值,數(shù)組的內(nèi)容會變化? var arr = [1]; arr.length = 3; aler...
摘要:的擴展知識對于哈希表來說,最重要的莫過于生成哈希串的哈希算法和處理沖突的策略了。由于鏈表的查找需要遍歷,如果我們將鏈表換成樹或者哈希表結(jié)構(gòu),那么就能大幅提高沖突元素的查找效率。 最近在整理數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的知識,小茄專門在github上開了個repo https://github.com/qieguo2016...,后續(xù)內(nèi)容也會更新到這里,歡迎圍觀加星星! js對象 js中的對象是基...
摘要:有需要還可以修改指向謙龍寄生組合式繼承思路是通過借用構(gòu)造函數(shù)來繼承屬性,通過原型鏈的混合形式來繼承方法改變執(zhí)行環(huán)境實現(xiàn)繼承有需要還可以修改指向謙龍謙龍拷貝繼承該方法思路是將另外一個對象的屬性和方法拷貝至另一個對象使用遞歸 前言 js中實現(xiàn)繼承的方式只支持實現(xiàn)繼承,即繼承實際的方法,而實現(xiàn)繼承主要是依靠原型鏈來完成的。 原型鏈式繼承 該方式實現(xiàn)的本質(zhì)是重寫原型對象,代之以一個新類型的實例...
閱讀 2800·2021-09-01 10:30
閱讀 1690·2019-08-30 15:52
閱讀 979·2019-08-29 18:40
閱讀 1134·2019-08-28 18:30
閱讀 2405·2019-08-23 17:19
閱讀 1333·2019-08-23 16:25
閱讀 2711·2019-08-23 16:18
閱讀 2988·2019-08-23 13:53