我们创建的每个函数都有一个 prototype (原型)属性,这个属性是一个指针,指向一个原型对象,而这个原型对象中拥有的属性和方法可以被所以实例共享。
rush:js;">
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
一、理解原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个 prototype属性,这个属性指向函数的原型对象。
在默认情况下,所有原型对象都会自动获得一个 constructor(构造函数)属性,这个属性包含一个指向 prototype 属性所在函数的指针。
当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262 第 5 版中管这个指针叫 [[Prototype]] 。
虽然在脚本中没有标准的方式访问 [[Prototype]] ,但 Firefox、Safari 和 Chrome 在每个对象上都支持一个属性__proto__ ;而在其他实现中,这个属性对脚本则是完全不可见的。
不过,要明确的真正重要的一点就是,这个连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。
以前面使用 Person 构造函数和 Person.prototype 创建实例的代码为例,图 6-1 展示了各个对象之间的关系。
在此, Person.prototype 指向了原型对象,而 Person.prototype.constructor 又指回了 Person 。
person1 和 person2 都包含一个内部属性,该属性仅仅指向了 Person.prototype ;换句话说,它们与构造函数没有直接的关系。
可以调用 person1.sayName() 。这是通过查找对象属性的过程来实现的。(会先在实例上搜索,如果搜索不到就会继续搜索原型。)
<div class="jb51code">
<pre class="brush:js;">
用isPrototypeOf()方法判断实例与原型对象之间的关系alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true用Object.getPrototypeOf() 方法返回实例的原型对象alert(Object.getPrototypeOf(person1) == Person.prototype); //true使用 hasOwnproperty() 方法可以检测一个属性是存在于实例中,还是存在于原型中。alert(person1.hasOwnProperty("name")); //false 来着原型person1.name = "Greg";alert(person1.name); //"Greg"——来自实例alert(person1.hasOwnProperty("name")); //true
rush:js;">
function Person(){
}
Person.prototype = {
name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () {
alert(this.name);
}
};
rush:js;">
var friend = new Person();
alert(friend instanceof Object); //true
alert(friend instanceof Person); //true
alert(friend.constructor == Person); //false
alert(friend.constructor == Object); //true
rush:js;">
function Person(){
}
Person.prototype = {
constructor : Person,name : "Nicholas",age : 29,job: "Software Engineer",sayName : function () {
alert(this.name);
}
};
rush:js;">
function Person(){
}
Person.prototype = {
constructor: Person,job : "Software Engineer",friends : ["Shelby","Court"],sayName : function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Van"
alert(person1.friends === person2.friends); //true
rush:js;">
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
//继承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue()); //true