原型的幾點總結
一、一切引用類型都是對象。
JavaScript分為基本包裝類型(值類型)和引用類型,引用類型是對象。引用類型主要有函數,數組,對象,null,因此它們都是對象。
判斷一個變量是不是變量,值類型可以用typeof來判斷,引用類型則可以用instanceof來判斷。
console.log(typeof [1,2,3]); //object
var fn = function(){};
console.log(fn instanceof Object); //true
對象:若干屬性的集合,屬性以鍵值對的形式出現。
var obj = {
a:10,
b:function(){
console.log(this.a);
},
c:{
name:"沈鵬",
year:22
}
}
obj有a,b,c三個屬性,同時c又有兩個屬性,所有對象是若干屬性的集合。
因此,根據以上內容得出“一切引用類型是對象,對象是若干屬性的集合”。
二、對象是函數創建的。
// var obj = { a: 1, b: 2 };
// var arr = [1, 'x', true];
var obj = new Object();
obj.a = 10;
obj.b = 20;
var arr = new Array();
arr[0] = 5;
arr[1] = 'x';
arr[2] = true;
然后通過typeof來檢測一下
console.log(typeof (Object)); // function console.log(typeof (Array)); // function
因此通過以上兩段代碼得出,對象是由函數創建的。
三、隱式原型
函數也是對象,函數也有一個屬性叫做prototype,它也是一個對象,該對象有一個默認的constructor屬性,它指向這個函數本身。可以用紅寶書中的圖來表示:

另外,這個prototype對象可以自己增加屬性來擴充。如superType.prototype.name = '沈鵬‘。
隱式原型的由來:創建的對象都有一個隱藏的—proto—屬性,這個屬性引用了創建這個對象的函數的prototype,也即proto指向了prototype。
四、原型鏈
圖示:

幾點說明:
一是這個原型鏈的例外就是object.prototype,它的-proto-指向null。這個是需要我們切記的。
二是,自定義函數是由Fuction創建的,所以自定義函數的-proto-指向Function.prototype.
三是,function Object()是一個構造函數,因此也是由Function來創建的,所以fuction Object()的-proto-也會指向Function.ptototype;
四是,Function.prototype指向的對象和Foo.prototype指向的對象都是由object創建的,所以它們兩個的prototype都會指向object.prototype.
五、繼承的由來
instanceof判斷類型的原理和判斷規則:
Instanceof運算符的第一個變量是一個對象,暫時稱為A;第二個變量一般是一個函數,暫時稱為B。
Instanceof的判斷隊則是:沿著A的__proto__這條線來找,同時沿著B的prototype這條線來找,如果兩條線能找到同一個引用,即同一個對象,那么就返回true。如果找到終點還未重合,則返回false。
instanceof表示的就是一種繼承關系,或者原型鏈的結構,所以JavaScript的繼承通過原型鏈來實現的。
function Foo(){};
var f1 = new Foo();
f1.a = 1;
f1.prototype.a = 10;
f1.prototype.b = 20;
console.log(f1.a); //1
console.log(f1.b); //20

訪問一個對象的屬性時,先在基本屬性中查找,如果沒有,再沿著__proto__這條鏈向上找,這就是原型鏈。
有了這個繼承規則,我們才能理解到為什么所有的對象均有Object.prototype的屬性和方法。因為所有的對象都會沿著-proto-這條鏈找到Object.prototype。

類似的,我們也自然知道了函數方法的由來了。函數由Function函數創建,因此繼承的Function.prototype中的方法。

六、總結
以上就是關于JavaScript原型鏈的一點總結,有不對之處請批評指正。
參考:
http://www.rzrgm.cn/wangfupeng1988/p/3977924.html 這篇博文寫的很詳細,通俗易懂。
浙公網安備 33010602011771號