? ? ? ? 大家好猎莲,我是IT修真院北京總院第29期的學(xué)員禚洪宇,一枚正直技即、純潔益眉、善良的前端程序員今天給大家分享一下,修真院官網(wǎng)JS任務(wù)5深度思考中的知識點——原型鏈是什么姥份?有什么功能郭脂?若想訪問一個對象的原型,應(yīng)該使用什么方法澈歉?
1 背景介紹
1.1什么是原型
學(xué)習(xí)原型鏈之前我們首先要明白什么是原型展鸡;那么什么是原型呢?我們來簡單學(xué)習(xí)一下:
只要我們像這樣簡單的定義一個函數(shù)foo(),就可以訪問像訪問其他對象一樣訪問該函數(shù)的屬性:
>>>function foo(a,b){return a*b;}
>>>foo.length
2
>>>foo.constructor
Function()
其實我們在創(chuàng)建一個函數(shù)的時候埃难,這個函數(shù)就包括了prototype屬性莹弊,它的初始值是一個空對象(object),
>>>typeof foo.prototype
"object"
所以我們可以自己在這個空對象中添加屬性涡尘,像這樣:
>>>foo.prototype = {}
1.2 原型有什么作用
? ? ? ? 簡述一下prototype屬性的出現(xiàn):
? ? ? ? 第一版瀏覽器無用戶交互—》需要腳本語言—》借鑒C++和Java語言忍弛,又想節(jié)省服務(wù)器資源和時間—》prototype。
? ? ? ? ?由于所有的實例對象共享同一個prototype對象考抄,那么從外界看起來细疚,prototype對象就好像是實例對象的原型,而實例對象則好像"繼承"了prototype對象一樣川梅。
? ? ? ? ? 這個屬性包含一個對象(以下簡稱"prototype對象")疯兼,所有實例對象需要共享的屬性和方法,都放在這個對象里面贫途;那些不需要共享的屬性和方法吧彪,就放在構(gòu)造函數(shù)里面。
? ? ? ??而實例對象一旦創(chuàng)建丢早,將自動引用prototype對象的屬性和方法姨裸。也就是說,實例對象的屬性和方法怨酝,分成兩種傀缩,一種是本地的,另一種是引用的凫碌。
2 知識剖析
2.1 原型鏈是什么
? ? ? ? 我們上面說到扑毡,每個構(gòu)造函數(shù)在創(chuàng)建時都包含一個屬性prototype,其初始值是一個空對象;
原型對象結(jié)構(gòu):
Function.prototype={?
?constructor :Function,
__proto__:parentprototype,
someprototypeproperties: ...?
?};
? ? ? ?函數(shù)的原型對象constructor默認指向函數(shù)本身盛险,原型對象除了有原型屬性外瞄摊,為了實現(xiàn)繼承勋又,還有一個原型鏈指針__proto__,該指針指向上一層的原型對象换帜,而上一層的原型對象的結(jié)構(gòu)依然類似楔壤,這樣利用__proto__一直指向Object的原型對象上,而Object的原型對象用Object.prototype.__proto__ = null表示原型鏈的最頂端惯驼,如此變形成了javascript的原型鏈繼承蹲嚣,同時也解釋了為什么所有的javascript對象都具有Object的基本方法。
2.2 若想訪問一個對象的原型祟牲,應(yīng)該使用什么方法隙畜?
獲取實例對象obj的原型對象,有三種方法
1. obj.__proto__
2. obj.constructor.prototype
3. Object.getPrototypeOf(obj)
上面三種方法之中说贝,前兩種都不是很可靠议惰。最新的ES6標準規(guī)定,__proto__屬性只有瀏覽器才需要部署,其他環(huán)境可以不部署。而obj.constructor.prototype在手動改變原型對象時环戈,可能會失效。
3 常見問題
Array.isArray(Array.prototype)輸出什么运杭?
4 解決方案
Array.prototype是Array構(gòu)造函數(shù)實例的原型,構(gòu)造函數(shù)實例化后仍為數(shù)組函卒,所以輸出true辆憔。
5 擴展思考
Q1:? prototype與_proto_是什么關(guān)系
__proto__(隱式原型)、prototype(顯式原型)
A1:?? 顯式原型 explicit prototype property:每一個函數(shù)在創(chuàng)建之后都會擁有一個名為prototype的屬性谆趾,這個屬性指向函數(shù)的原型對象躁愿。
隱式原型 implicit prototype link:JavaScript中任意對象都有一個內(nèi)置屬性[[prototype]],在ES5之前沒有標準的方法訪問這個內(nèi)置屬性沪蓬,但是大多數(shù)瀏覽器都支持通過__proto__來訪問。ES5中有了對于這個內(nèi)置屬性標準的Get方法Object.getPrototypeOf().
二者的關(guān)系:
隱式原型指向創(chuàng)建這個對象的函數(shù)(constructor)的prototype
Q2:在IE中可以使用_proto_屬性嗎来候?
A:_proto_將在ES6中進行標準化跷叉,目前在ES6的草案附錄B中。
Q3:_proto_的兼容性怎么樣营搅?
A:_proto_目前是瀏覽器的內(nèi)置屬性云挟,不同的瀏覽器有不同的情況。
6?參考文獻
參考一:阮一峰:Javascript繼承機制的設(shè)計思想
參考三:談?wù)剬υ玩湹睦斫?/a>
參考四:《JavaScript面向?qū)ο缶幊讨改稀?/p>