深入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。上面的代码创建的原型链如下

用下面这个例子来展示原型动态特性的魅力的,以免在程序中整出很神奇的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调试信息如下:

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

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

posted @ 2011-06-27 08:09  秋无语  阅读(429)  评论(2编辑  收藏  举报