原型 原型鏈 筆記

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	</body>
	<script type="text/javascript">
		
第一篇

	1,普通對象和函數對象	object	function

		var obj = {};

		var obj = new Object();

		obj.constructor === Object

		obj.__proto__ === Object.prototype	實例的__proto__等於構造函數的原型對象 Object.prototype
	
	2,構造函數
	
		//	每一個對象都有一個 constructor 屬性,能夠獲取它的構造函數。

		//	constructor 構造函數

		//	實例的構造函數屬性(constructor)指向構造函數。			*

		
	
	3,原型對象
	
		//	每一個對象都有 __proto__ 屬性,但只有函數對象纔有 prototype 屬性
		
		//	原型對象,顧名思義,它就是一個普通對象	Person.prototype = {name:'tom',age:18}
		
		//	在默認狀況下,全部的原型對象都會自動得到一個 constructor(構造函數)屬性,這個屬性(是一個指針)指向 prototype 屬性所在的函數(Person)
		
			結論:原型對象(Person.prototype)是 構造函數(Person)的一個實例。

第二篇
	
	4,__proto__
	
		JS 在建立對象(不管是普通對象仍是函數對象)的時候,都有一個叫作__proto__ 的內置屬性,用於指向建立它的構造函數的原型對象。			
		Person.prototype.constructor == Person;
		person1.__proto__ == Person.prototype;
		person1.constructor == Person;
		
	5,構造器

		熟悉 Javascript 的童鞋都知道,咱們能夠這樣建立一個對象:
		var obj = {}
		
		它等同於下面這樣:
		var obj = new Object()
		
		obj 是構造函數(Object)的一個實例。因此:
		obj.constructor === Object
		obj.__proto__ === Object.prototype
		
		同理,能夠建立對象的構造器不單單有 Object,也能夠是 Array,Date,Function , String ,Boolean ,Number ,等。因此咱們也能夠構造函數來建立 Array、 Date、Function, 這些構造器都是函數對象
	
	6.原型鏈
	
		Object.prototype.__proto__ === null;


第三篇
	
	7.函數對象
	
		//	全部函數對象的proto都指向Function.prototype,它是一個空函數(Empty function)

		//	全部的構造器都來自於Function.prototype,甚至包括根構造器Object及Function自身
		
		Number.__proto__ === Function.prototype  // true
		Number.constructor == Function //true

		Boolean.__proto__ === Function.prototype // true
		Boolean.constructor == Function //true

		// 全部的構造器都來自於Function.prototype,甚至包括根構造器Object及Function自身
		Object.__proto__ === Function.prototype  // true
		Object.constructor == Function // true

		// 全部的構造器都來自於Function.prototype,甚至包括根構造器Object及Function自身
		Function.__proto__ === Function.prototype // true
		Function.constructor == Function //true

		Array.__proto__ === Function.prototype   // true
		Array.constructor == Function //true

		Date.__proto__ === Function.prototype    // true
		Date.constructor == Function //true
		
		// 函數聲明
		function Person() {}
		// 函數表達式
		var Perosn = function() {}
		console.log(Person.__proto__ === Function.prototype) // true
		
		
		** 全部的構造器都來自於 Function.prototype,甚至包括根構造器Object及Function自身。全部構造器都繼承了·Function.prototype·的屬性及方法。如length、call、apply、bind **

		//	Function.prototype也是惟一一個typeof XXX.prototype爲 function的prototype。其它的構造器的prototype都是一個對象
		console.log(typeof Function.prototype) // function
		console.log(typeof Object.prototype)   // object
		console.log(typeof Number.prototype)   // object
		console.log(typeof Boolean.prototype)  // object
		console.log(typeof String.prototype)   // object
		console.log(typeof Array.prototype)    // object
		console.log(typeof RegExp.prototype)   // object
		console.log(typeof Error.prototype)    // object
		console.log(typeof Date.prototype)     // object
		console.log(typeof Object.prototype)   // object
		
		知道了全部構造器(含內置及自定義)的__proto__都是Function.prototype,那Function.prototype的__proto__是誰呢?
		
		相信都據說過JavaScript中函數也是一等公民,那從哪能體現呢?以下console.log(Function.prototype.__proto__ === Object.prototype) // true、
		
		這說明全部的構造器也都是一個普通JS對象,能夠給構造器添加/刪除屬性等。同時它也繼承了Object.prototype上的全部方法:toString、valueOf、hasOwnProperty等
		
		最後Object.prototype的proto是誰?	Object.prototype.__proto__ === null			已經到頂了,爲null。(讀到如今,再回過頭看第五章,能明白嗎?)
		


	8,prototype
		
		全部函數對象proto都指向 Function.prototype,它是一個空函數(Empty function)
		
		Object.getOwnPropertyNames(Function.prototype)	因此全部的函數對象都能用
		
	9,複習一下
	
		第八小節咱們總結了:全部函數對象的 __proto__ 都指向 Function.prototype,它是一個空函數(Empty function)
		
		可是你可別忘了在第三小節咱們總結的:全部對象的 __proto__ 都指向其構造器的 prototype
	
	10,原型鏈(在複習一下)
	
		function Person(){}
		var person1 = new Person();
		console.log(person1.__proto__ === Person.prototype); // true
		console.log(Person.prototype.__proto__ === Object.prototype) //true
		console.log(Object.prototype.__proto__) //null

		Person.__proto__ == Function.prototype; //true
		console.log(Function.prototype)// function(){} (空函數)

		var num = new Array()
		console.log(num.__proto__ == Array.prototype) // true
		console.log( Array.prototype.__proto__ == Object.prototype) // true
		console.log(Array.prototype) // [] (空數組)
		console.log(Object.prototype.__proto__) //null

		console.log(Array.__proto__ == Function.prototype)// true
		
		疑點解惑:
		
			1,Object.__proto__ === Function.prototype // true
				Object 是函數對象,是經過new Function()建立的,因此Object.__proto__指向Function.prototype。(參照第八小節:「全部函數對象的__proto__都指向Function.prototype」)

			2,Function.__proto__ === Function.prototype // true  Function 也是對象函數,也是經過new Function()建立,因此Function.__proto__指向Function.prototype。

			3,	Function.prototype.__proto__ === Object.prototype //true
			
				其實這一點我也有點困惑,不過也能夠試着解釋一下。
				Function.prototype是個函數對象,理論上他的__proto__應該指向 Function.prototype,就是他本身,本身指向本身,沒有意義。
				JS一直強調萬物皆對象,函數對象也是對象,給他認個祖宗,指向Object.prototype。Object.prototype.__proto__ === null,保證原型鏈可以正常結束。
	
	11,總結
			
			原型和原型鏈是JS實現繼承的一種模型。
			
			原型鏈的造成是真正是靠__proto__ 而非prototype
			
			var animal = function(){};
			var dog = function(){};

			animal.price = 2000;
			dog.prototype = animal;
			var tidy = new dog();
			console.log(dog.price) //undefined
			console.log(tidy.price) // 2000
			
			var dog = function(){};
			dog.prototype.price = 2000;
			var tidy = new dog();
			console.log(tidy.price); // 2000
			console.log(dog.price); //undefined
			 
			var dog = function(){};
			var tidy = new dog();
			tidy.price = 2000;
			console.log(dog.price); //undefined
			
			
			實例(tidy)和原型對象(dog.prototype)存在一個鏈接。不過,要明確的真正重要的一點就是,這個鏈接存在於實例(tidy)與構造函數的原型對象(dog.prototype)之間,
			而不是存在於實例(tidy)與構造函數(dog)之間。




評論:

	1,博主大部分都分析的能夠了,就是原型鏈沒有說清楚,致使評論出現誤解,實例沒有的屬性,js會嘗試往原型對象上找,原型對象上沒有,再往原型對象的__proto__(Object.prototype)上找,
	
	最終會找到Object.prototype._proto_(他就是原型鏈的終點null),找到就返回對應的值,沒找到就返回undefined
	
	2,剛聽了下同事的講解,豁然開朗,一個是原型對象,一個是創造自身的原型對象,也能夠理解爲上一級。
	
筆記:
	
	
	
	
	
	
	
	
	
	</script>
</html>
相關文章
相關標籤/搜索