*内容
---关于创建javascript的对象,将说明如下问题:
1)new操作符做了些什么
2)属性prototype,constructor的含义
---关于instanceof的含义
*示例,演示原型机制
---源码(下载)
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 }
--- 运行结果
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特性
---源码(下载)
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");
---结果
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为提供复用性而采取的一种"继承"策略, 多个对象共享一个原型, 通过牺牲时间换取了更多的内存空间, 语言的特性和发展和其历史环境有关系;
---简单又灵活, 也易对编程产生更多不安全因素; 可以学习一些设计模型, 以便开发可控的,安全的对象. 简单是一种美.
*参考