原型 原型链 笔记

<!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>

  

猜你喜欢

转载自www.cnblogs.com/jeff-zhu/p/11423389.html