轉(zhuǎn)載至: JS原型鏈詳解
JS是基于對象的語言气嫁,原型對象是其模擬面向?qū)ο蟮囊环N方式,關(guān)于原型有兩種表現(xiàn)形式:一種是proto (隱式原型) 一種是prototype(顯式原型)耍属,這兩個名詞形成了原型鏈的愛恨情仇。
下面我們看下這兩個原型出自哪里巩检,比較重要
下面的圖片是從知乎上面弄下來的祖?zhèn)骼蠄D厚骗,被我挖過來了
下面總(chao)結(jié)(xi)了幾條原型的概念,然后就不難理解上面的這幅圖了
1 . 任何對象都擁有 proto(隱式原型) 屬性, 一般指向他們的構(gòu)造函數(shù)的原型 (prototype) .
var a = new Array ()
// a 是一個數(shù)組對象 默認擁有__proto__ 屬性
console.log(a.__proto__ === Array.prototype); // true
2 . 原型鏈的頂端是Object.prototype兢哭,其 proto為 null
console.log(Object.prototype.__proto__ === null); // true
3 . 所有函數(shù)都擁有prototype (顯式原型)屬性
同最上面的圖领舰,實例(對象/構(gòu)造函數(shù)new 出來的東西)存在proto,函數(shù)/方法存在prototype(萬物皆對象,也存在proto,指向下面的Function)
4 . 所有函數(shù)都是Function 的 實例
function fn () {
}
// fn 是 Function 構(gòu)造函數(shù)創(chuàng)建出來的
console.log(fn.__proto__ === Function.prototype); // true
console.log(obj.__proto__ === Object.prototype); // true
console.log(arr.__proto__ === Array.prototype); // true
5 . Object Function Array 本身也都是一個函數(shù)迟螺,由于是最常用的冲秽,所以JavaScript幫我們實現(xiàn)了
// 當我們通過構(gòu)造函數(shù)的方式來創(chuàng)建一個對象 ,其本質(zhì)也是new一個普通的函數(shù)
// 因此可以得出
console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype ); // true
console.log(Array.__proto__ === Function.prototype); // true
6 . 原型對象中又擁有constructor屬性,該屬性指向函數(shù)本身,這個好理解(constructor為構(gòu)造器矩父,不修改的情況下prototype.constructor等于自己)
console.log(Function.prototype.constructor === Function); // true
console.log(Object.prototype.constructor === Object); // true
console.log(Array.prototype.constructor === Array); // true
7 . 原型鏈 概念
如果想要找到一個對象的屬性,首先會先在自身查找,如果沒有,就會通過proto屬性一層層的向上查找,直到原型鏈的頂端 Object.prototype(proto: null)锉桑,這種通過某種紐帶(proto)將對象之間形成一種繼承關(guān)系 這種關(guān)系呈現(xiàn)出一種鏈條的形狀 將這種鏈條稱之為原型鏈
function foo(name) {
this.name = name;
}
foo.prototype = {
showName: function() {console.log(this.name)}
}
var zyc = new foo('zyc');
zyc.showName = function(){ console.log('superMan') };
zyc.showName(); // superMan
// 刪除了本身屬性,查構(gòu)造函數(shù)的prototype窍株,不行再去查Object和Function的prototype
delete zyc.showName;
zyc.showName(); // zyc
8 . 根據(jù)第 6 條可以推論得:
console.log(fn.constructor===Function); // true
// fn自身并沒有constructor屬性,所以他會順著原型鏈向上找
// 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是一個特殊的例子 他創(chuàng)造了所有的函數(shù),但他自身就是也是一個函數(shù) 總不能自己創(chuàng)造自己吧 所以他的上級是 Object.prototype