*内容

---关于创建javascript的对象,将说明如下问题:

1)new操作符做了些什么

2)属性prototype,constructor的含义

---关于instanceof的含义

 

*示例,演示原型机制

---源码(下载)

t_object.js
 1 function testObject(object){
 2     if(!typeof object == "object")
 3         return;
 4 
 5     console.log("object.constructor: " + object.constructor.toString());
 6 
 7     if(object.prototype){ //false, 对象没有prototype属性
 8         console.log("object.prototype.constructor: " + object.prototype
 9                     .toString());
10     }
11 
12     if(object.__proto__){ //通过内部不可见指针__proto__找到原型对象; 这里运行环境Node,这个属性可见
13         console.log("object.__proto__.constructor: " + object.__proto__.constructor.toString());
14         console.log("__proto__ is not Null");
15         console.log("object.__proto__: " + object.__proto__.toString()); //BasicObject实例的原型是一个Object,而不是null
16     }
17 
18     console.log("object.constructor.prototype: " + object.constructor.prototype.name);
19 
20     if(object.name){
21         console.log("object.name: " + object.name);
22     }
23 
24     if(object instanceof object.constructor)
25         console.log("instanceof True");
26     else
27         console.log("instanceof False");
28 }
29 
30 //test 1
31 console.log("Test 1: ");
32 function BasicObject(){
33     console.log("new BasicObject()");
34     this.name = "BasicObject";
35 }
36 
37 var obj = new BasicObject();
38 testObject(obj);
39 if(obj.isPrototypeOf(obj)){
40     console.log("prototype is itself");
41 }
42 console.log("BasicObject.prototype: "+BasicObject.protoype); //undefined
43 
44 //test 2
45 console.log("Test 2: ");
46 function ProtoObject(){
47     console.log("new ProtoObject()");
48 //    this.name = "ProtoObject";
49 }
50 ProtoObject.prototype = new BasicObject();
51 //console.log("prototype: "+ProtoObject.prototype.toString());
52 
53 testObject(new ProtoObject());
54 
55 //test 3
56 console.log("Test 3: ");
57 function ConstructorObject(){
58     console.log("new ConstructorObject()");
59     this.constructor = ConstructorObject;
60 }
61 ConstructorObject.prototype = new BasicObject();
62 
63 testObject(new ConstructorObject());
64 
65 //test null
66 console.log("Test null: ");
67 if(null === null){ // is true
68     console.log("null === null");
69 }
70 if(!null){
71     console.log("null is false");
72 }

 

--- 运行结果

Node运行结果
Test 1: 
new BasicObject()
object.constructor: function BasicObject(){
    console.log("new BasicObject()");
    this.name = "BasicObject";
}
object.__proto__.constructor: function BasicObject(){
    console.log("new BasicObject()");
    this.name = "BasicObject";
}
__proto__ is not Null
object.__proto__: [object Object]
object.constructor.prototype: undefined
object.name: BasicObject
instanceof True
BasicObject.prototype: undefined
Test 2: 
new BasicObject()
new ProtoObject()
object.constructor: function BasicObject(){
    console.log("new BasicObject()");
    this.name = "BasicObject";
}
object.__proto__.constructor: function BasicObject(){
    console.log("new BasicObject()");
    this.name = "BasicObject";
}
__proto__ is not Null
object.__proto__: [object Object]
object.constructor.prototype: undefined
object.name: BasicObject
instanceof True
Test 3: 
new BasicObject()
new ConstructorObject()
object.constructor: function ConstructorObject(){
    console.log("new ConstructorObject()");
    this.constructor = ConstructorObject;
}
object.__proto__.constructor: function BasicObject(){
    console.log("new BasicObject()");
    this.name = "BasicObject";
}
__proto__ is not Null
object.__proto__: [object Object]
object.constructor.prototype: BasicObject
object.name: BasicObject
instanceof True
Test null: 
null === null
null is false

  

*回答初始问题

---new做了些什么

1)创建对象:创建新对象->构造函数作用域赋给新对象->执行构造器代码->返回新对象;

2)设置原型:创建的新对象有一个不可见的属性(一般是__proto__,但是我在Node中测试这个属性可见),其指向构造器函数的prototype属性指向的原型对象值;

3)设置constructor:创建的新对象有一个constructor属性,指向构造函数.prototype.constructor指向的构造函数;

4)对于没有自定义prototype属性的构造数,新对象默认设置的原型为new Object()(这是从测试程序在Node上运行的结果和下面的摘要分析出的结论)

"All objects have an internal property called [[Prototype]]. The value of this property is either null or an object
and is used for implementing inheritance." ---Ecma-262

此时,可以说new相当于这样:新对象.__proto__ = new Object();新对象.constructor = 新对象的构造器.

(这是一个推论,还没找到在语言定义上的明确说明,后面有时间仔细看看Ecma).

---属性prototype

构造函数的属性,保存了所有这个构造函数生成的对象的原型对象

---属性constructor

1)对象属性,说明了这个对象是由哪个构造函数生成的;

2)赋值规则:若构造函数有原型,则其值为原型的constructor(此时,通常需要自己在构造器中手动指定); 若构造函数没有定义原型, 则默认当前这个构造函数;

3)constructor的主要用处,在于通过'对象.constructor'可获取原型对象.

 

*示例,演示instanceof特性

---源码(下载)

t_instanceof
 1 function ObjA(){}
 2 
 3 function ObjB(){
 4     this.constructor = ObjB;
 5 }
 6 ObjB.prototype = new ObjA();
 7 
 8 var objA = new ObjA();
 9 var objB = new ObjB();
10 
11 if(objA instanceof Object)
12     console.log("objA instanceof Object is true");
13 if(objA instanceof ObjA)
14     console.log("objA instanceof ObjA is true");
15 
16 if(objB instanceof Object)
17     console.log("objB instanceof Object is true");
18 if(objB instanceof ObjB)
19     console.log("objB instanceof ObjB is true");
20 if(objB instanceof ObjA)
21     console.log("objB instanceof ObjA is true");

 

---结果

Node运行结果
objA instanceof Object is true
objA instanceof ObjA is true
objB instanceof Object is true
objB instanceof ObjB is true
objB instanceof ObjA is true

  

*总结instanceof

---格式: 对象 instanceof 构造函数

当构造函数是对象的constructor, 或者是原型对象的constructor时,返回true,否则返回false

 

*总结

---js对象, 简单说就是一个无序的key/value集合; 

---原型机制,是js为提供复用性而采取的一种"继承"策略, 多个对象共享一个原型, 通过牺牲时间换取了更多的内存空间, 语言的特性和发展和其历史环境有关系;

---简单又灵活, 也易对编程产生更多不安全因素; 可以学习一些设计模型, 以便开发可控的,安全的对象. 简单是一种美.

 

*参考

http://www.mollypages.org/misc/js.mp

http://bclary.com/2004/11/07/#a-15.3.5.2

posted on 2012-06-03 04:27  戴忠  阅读(600)  评论(0编辑  收藏  举报