原型与原型链

261 阅读3分钟

原型与原型链

普通对象与函数对象

通过new Function() 创建的对象是函数对象,其他的都是普通对象。 Function Object也是通过new Function()来创建的,也是函数对象。 Object 、Function 是JavaScript自带的函数对象。

例如:

o1,o2,o3为普通对象

f1,f2,f3为函数对象(f1,f2都是通过new function()创建的)

构造函数

实例的构造函数属性(constructor)指向构造函数

function Person(name, age, job) {
 this.name = name;
 this.age = age;
 this.job = job;
 this.sayName = function()
    { 
    alert(this.name);
    } 
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");

person1 和 person2 都有一个 constructor属性,该属性是一个指针,指向 Person。

原型

在JavaScript中,原型也是一个对象。每当定义一个对象时,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。

使用原型对象的好处是可以让所有的对象实例共享他所包含的属性和方法。即不必在构造函数中定义对象实例信息,而是可以将这些信息直接添加到原型对象中

原型和类的继承的用法是一致的,(对象的原型可以理解为对象的父对象)若使用某个对象的属性时,将当前对象的原型指向该对象,就可以使用该对象。

原型模式缺点:它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。

原型对象

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性。这个属性包含一个指向prototype属性所在函数的指针。

原型对象就是构造函数的一个实例

原型链

原型链是由原型对象组成,每个对象都有proto属性,指向了创建该对象的构造函数的原型,proto将对象连接起来形成了一个链条———原型链。是一个用来实现继承和共享属性的有限的对象链。

查找:当查找对象的属性时,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象Object.prototype,如果还是没找到,则输出undefined;

普通对象和函数对象都具有原型链__proto__属性,但函数对象还有一个原型propotype属性

注意

javascript中一切皆对象,函数也属于对象。

所有对象都含有__proto__。

只有函数才有prototype。

所有函数的默认原型都是Object的实例。

举例

下面来看一个例子例子...

	function Person(name) {
	    this.name = name
	}
	var person1 = new Person("G");
	
	
	   	
	console.log(person1.constructor)
	//constructor属性是一个指针,指向Person
	
	console.log(person1.prototype)
	//p2是实例对象,不是函数对象,没有prototype属性。输出结果为undefined
	
	console.log(Person.constructor)
	//function
	
	console.log(Person.prototype)
	//输出Person.prototype这个对象里所有的方法和属性
	
	console.log(Person.prototype.constructor)
	//Person
	
	console.log(Person.prototype.__proto__)
	//Person.prototype是一个对象,所以输出结果为Object.prototype
	
	console.log(Person.__proto__)
	//Function.prototype
	
	console.log(person1.__proto__)
	//Person.prototype
	
	console.log(person1.__proto__.__proto__)
	//求Person.prototype的__proto__,因为Person.prototype自己就是一个对象,所以这里指向为Object.prototype
	
	console.log(person1.__proto__.__proto__.__proto__)
	//Object.prototype的__proto__,输出则为null
	
	console.log(person1.__proto__.__proto__.__proto__.__proto__)
	//因为null后面没有__proto__了,所以这里会报错!