js原型鏈

java小新人發表於2019-06-29

目錄

  • 1.物件的原型和原型鏈
    • 1.1什麼是原型
    • 1.2檢視原型
    • 1.3物件的原型鏈
  • 2.使用建構函式
    • 2.1 函式的原型鏈
    • 2.2 函式的prototype屬性
    • 2.3 例項與建構函式的原型鏈
    1. 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	
複製程式碼

js原型鏈
最後再貼一張別人總結的混亂關係圖
js原型鏈

相關文章