深入JavaScript对象

ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数“。我们可以把ECMAScript的对象想象成散列表:一组名值对,其中值可以使数据或函数。每个函数都有一个prototype属性,这个属性是一个对象,prototype对象的属性和方法被类型的所有实例共享。Prototype就是通过调用构造函数而创建的那个对象的原型对象。对象通过一个内部属性_proto_绑定到它的原型,这个属性在Firefox,Safari和Chrome浏览器中对开发者可见。所有函数对象的protoType默认指向object对象的原型。如:

  
  
< script language = " javascript " type = " text/javascript " >
function Person(name, address) {
this .name = name;
this .address = address;
}
Person.prototype.say
= function () {
alert(
this .name);
}
var person1 = new Person( " Feng " , " Henan " );
var person2 = new Person( " Lee " , " Beijing " );
alert(person1
instanceof Person); // true
alert(person1 instanceof Object); // true alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); // true
< / script>

构造器Person用来创建新实例。实例person1的原型(_proto_)指向Person.prototype。Person.prototype的原型指向Object.prototype。上面的代码创建的原型链如下

深入JavaScript对象_第1张图片

用下面这个例子来展示原型动态特性的魅力的,以免在程序中整出很神奇的BUG。需要用Firefox调试一把。

  
  
< script language = " javascript " type = " text/javascript " >
function Person() {
}
var person1 = new Person();
Person.prototype.sayOld
= function () {
alert(
" old test " );
};
// Person.prototype = {
//
name: "Feng",
//
address: "Henan",
//
say: function () {
//
alert(this.name);
//
}
//
};
// person1.say();错误不能调用
person1.sayOld();
alert(person1.__proto__.constructor);
var person2 = new Person();
alert(person2.__proto__.constructor);
alert(Person.prototype.constructor);
< / script>

注意person1是在添加sayOld方法之前创建的实例,此时调用sayOld()方法正常,firebug调试信息如下:

深入JavaScript对象_第2张图片

现在把person1.sayOld()注释掉,把注释掉的代码恢复正常,

深入JavaScript对象_第3张图片

但是person1.say()方法不能调用,因为我们重写了原型,person1指向的还是原来的原型,原来的原型不包括say方法。原型图如下:

深入JavaScript对象_第4张图片

你可能感兴趣的:(JavaScript)