目錄
- 1.物件的原型和原型鏈
- 1.1什麼是原型
- 1.2檢視原型
- 1.3物件的原型鏈
- 2.使用建構函式
- 2.1 函式的原型鏈
- 2.2 函式的prototype屬性
- 2.3 例項與建構函式的原型鏈
-
- Array Function Object關係
1.物件的原型和原型鏈
1.1 什麼是原型?
在java裡,物件導向的基本概念是類和物件,用類例項出物件,類之間能夠構建繼承關係,子類能夠呼叫父類的方法。
在js裡,少了一層類的概念,物件之間可以直接形成類似java裡繼承的關係,子物件可以呼叫父物件的屬性和方法。
js裡用“原型”來描述這種關係。
一個物件的__proto__屬性指向他的原型。
1.2 如何檢視原型
__proto__指向物件的原型
var A = {name : 'lili'};
console.log(typeof(A)); //object
console.log(A.__proto__ === Object.prototype);//true
複製程式碼
所有物件的原型都指向Object.prototype
1.3 物件原型鏈
物件的繼承中,涉及到三個角色 物件、物件.prpto、Object.prototype
console.log('********************comes B');
var B = {height : 168};
B.__proto__ = A; //手動改下原型,本來應該是Object.prototype
console.log(typeof(B)); //object
console.log(B.__proto__ === A); //true
console.log(B.height); //168
console.log(B.name); //lili
console.log(B.hasOwnProperty('name')); //false
console.log(B.hasOwnProperty('height')); //true
console.log('********************comes C');
var C = {say : function(){console.log('hello')}};
C.__proto__ = B;
console.log(typeof(C)); //object
console.log(C.__proto__ === B); //true
複製程式碼
- C的原型是B B的原型是A ,這就叫原型鏈。
- 當我們用obj.xxx訪問一個物件的屬性時,JavaScript引擎先在當前物件上查詢該屬性,如果沒有找到,就到其原型物件上找,如果還沒有找到,就一直上溯到Object.prototype物件,最後,如果還沒有找到,就只能返回undefined。
- 所以目前有__proto__和prototype兩個關鍵詞了。
- __proto__總是指向原型,用字面量建立的物件的原型都是Object.prototype,而不是Object。
- 物件可以直接呼叫父類的屬性,hasOwnProperty可以區分是繼承來的屬性還是自身的屬性。
2.使用建構函式
2.1建構函式的原型鏈
//寫一個建構函式
function Student(name) {
this.name = name;
this.hello = function () {
console.log('Hello, ' + this.name + '!');
}
};
//建構函式
console.log('*************************look at Student.__proto__');
console.log(typeof(Student)); //function
console.log(Student.__proto__ === Function.prototype); //true
console.log(Function.prototype.__proto__ === Object.prototype); //true
console.log(Student.__proto__.__proto__ === Object.prototype); //true
複製程式碼
所以 從建構函式到Object的
原型鏈是這樣的
某個函式->Functin.prototype->Object.prototype
Object.prototype這一層有一些方法比如hasOwnProperty isPrototypeOf toString
Function.prototype這一層有一些屬性比如arguments length name
2.2函式獨有的prototype屬性
另外,函式會有個prototype屬性,是函式獨有的,Object也有prototype屬性,因為Object的type也是function。
//只有函式和Object有prototype屬性,Object是function
console.log(typeof(Object)); //function
console.log(Student.prototype);
console.log(Student.prototype.__proto__ === Object.prototype);//true
console.log(Student.prototype.constructor === Student); //true
複製程式碼
prototype包含一個constructor和__proto__,而constructor指向他自己的物件,__proto__指向Object.prototype
因為constructor指向自己,所以能夠訪問到自己的各種方法,
constructor是構造物件中關鍵的一環
2.3例項與建構函式的原型鏈
//構造出來的物件
var zhangsan = new Student('張三');
zhangsan.name; //張三
zhangsan.hello(); //彈出hello張三
console.log('*************************look at zhangsan');
console.log(zhangsan);
console.log(typeof(zhangsan));//object
console.log(zhangsan instanceof Student); //true
console.log(zhangsan instanceof Student); //true
console.log(Student instanceof Object); //true
複製程式碼
zhangsan除了有正常的name和hello以為還有一個__proto__ 指向建構函式的prototype,
console.log('*************************look at zhangsan.__proto__');
console.log(zhangsan.__proto__ === Student.prototype);
console.log(Student.prototype.constructor.__proto__ === Function.prototype);
console.log(Student.prototype.constructor.__proto__.__proto__ === Object.prototype);
複製程式碼
3.Array Function Object關係
//函式的原型鏈
console.log('********************111111');
var f1 = function(){};
console.log(f1.__proto__ === Function.prototype); //true
console.log(Function.prototype.__proto__ === Object.prototype); //true
//陣列的原型鏈
console.log('********************222222');
var arr = [1,2]
console.log(arr.__proto__ === Array.prototype); //true
console.log(Array.prototype.__proto__ === Object.prototype); //true
//型別
console.log('********************33333');
console.log(typeof(f1)); //function
console.log(typeof(Function)); //function
console.log(typeof(arr)); //object
console.log(typeof(Array)); //function
console.log(typeof(Object)); //function
複製程式碼
最後再貼一張別人總結的混亂關係圖