圖文并茂的幫助你更好的理解JavaScript原型.
熟記并理解以下規(guī)則,保你深入理解對(duì)象原型,保你面試無憂.
1 . 任何對(duì)象都擁有 __proto__
(隱式原型) 屬性, 一般指向他們的構(gòu)造函數(shù)的原型 (prototype) .
var a = new Array ()
// a 是一個(gè)數(shù)組對(duì)象 默認(rèn)擁有__proto__ 屬性
console.log(a.__proto__ === Array.prototype); // true
// 白話就是 由誰創(chuàng)建 其__proto__ 就指向誰的 prototype
2 . 原型鏈的頂端是Object.prototype徘意,其 __proto__
為 null
console.log(Object.prototype.__proto__ === null); // true
// 這是一個(gè)特例,為了避免JavaScript死循環(huán).
3 . 所有函數(shù)都擁有prototype (顯式原型)屬性
任何函數(shù)的 prototype.__proto__ 都指向 Object.prototype 特例見第 2
4 . 所有函數(shù)都是Function 的 實(shí)例
function fn () {
// some code
}
// fn 是 Function 構(gòu)造函數(shù)創(chuàng)建出來的
// 因此 fn 的 __proto__ 屬性指向 Function 的 原型對(duì)象
console.log(fn.__proto__ === Function.prototype); // true
類似的 十分容易就能理解
var obj = {} // 可以看做是 var obj = new Object ()
var arr = [] // var obj = new Array ()
// 因此他們的構(gòu)造函數(shù)分別是 Object 和 Array
console.log(obj.__proto__ === Object.prototype); // true
console.log(arr.__proto__ === Array.prototype); // true
5 . 更奇葩的來了,Object Function Array 本身也都是一個(gè)函數(shù)岸晦,由于是最常用的凉唐,所以JavaScript幫我們實(shí)現(xiàn)了
// 當(dāng)我們通過構(gòu)造函數(shù)的方式來創(chuàng)建一個(gè)對(duì)象 凤优,其本質(zhì)也是new一個(gè)普通的函數(shù)
// 因此可以得出
console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype ); // true
console.log(Array.__proto__ === Function.prototype); // true
// 可印證 第4點(diǎn)
6 . 原型對(duì)象中又擁有constructor屬性,該屬性指向函數(shù)本身,這個(gè)好理解
console.log(Function.prototype.constructor === Function); // true
console.log(Object.prototype.constructor === Object); // true
console.log(Array.prototype.constructor === Array); // true
7 . 先普及一波 原型鏈 概念
如果想要找到一個(gè)對(duì)象的屬性,首先會(huì)先在自身查找,如果沒有,就會(huì)通過
__proto__
屬性一層層的向上查找,直到原型鏈的頂端 Object.prototype(__proto__: null
)
這種通過某種紐帶(__proto__
)將對(duì)象之間形成一種繼承關(guān)系 這種關(guān)系呈現(xiàn)出一種鏈條的形狀 將這種鏈條稱之為原型鏈
8 . 根據(jù)第 6 條可以推論得:
console.log(fn.constructor===Function); // true
// 解析:
// fn自身并沒有constructor屬性,所以他會(huì)順著原型鏈向上找
// fn.__proto__ 指向的是 Function.prototype 見第4
// Function.prototype.constructor === Function
console.log(Function.constructor === Function); // true
console.log(Object.constructor === Function); //true
9 . Function.prototype.__proto__ === Object.prototype
Function是一個(gè)特殊的例子 他創(chuàng)造了所有的函數(shù),但他自身也是一個(gè)函數(shù),他自己同時(shí)也創(chuàng)造了自己 此處見第 5 條 (感謝網(wǎng)友指出的錯(cuò)誤)
下面配合幾張?jiān)蛨D,幫助大家更好的理解.
構(gòu)造函數(shù)創(chuàng)建對(duì)象字面量原型圖
function Animal (color) {
this.color = color
}
var dog = new Animal ('黑色')
當(dāng)我們創(chuàng)建一個(gè)函數(shù)時(shí)原型如下:
完整對(duì)象字面量原型圖:
var obj = { name: '陳二狗' }
數(shù)組原型鏈
var arr = ['第一個(gè)數(shù)','第二個(gè)數(shù)','第三個(gè)數(shù)']
基本包裝類型原型鏈
var str = new String('str') // var str = 'str'
其實(shí)所有的原型鏈規(guī)則都是根據(jù)上面的規(guī)則來的,只要能記住并理解,那么你也就理解原型了
如果有紕漏 忘指出,如果有轉(zhuǎn)載,麻煩注明作者yucccc.