日期:2014-05-16 浏览次数:20351 次
代码咋一看很头疼,仔细看更头疼,反正我不会这么写代码。代码如下:
function aaa(sColor){ this.color = sColor; if(typeof aaa._is_ == "undefined"){ aaa.prototype.sayColor = function(){ alert(this.color); }; } aaa._is_ = true; } function bbb(sColor,name){ this.name = name; if(typeof bbb._iss_ == "undefined"){ bbb.prototype = new aaa(); bbb.prototype.sayName = function(){ alert(this.name); }; } bbb._iss_ = true; }
看完代码之后发现这是两个构造函数。先说第一个,在使用该函数创建第一个实例或者直接调用该函数(会污染全局对象)时向其原型中添加一个操作color属性的方法。代码正确性上没啥问题,用如下代码测试:
var a1 = new aaa("red");
var a2 = new aaa("green");
console.dir(a1);
console.dir(a2);
console.log(a1.__proto__ === a2.__proto__); // 输出true
现在说说第二个构造函数,在使用该函数创建第一个实例或者直接调用该函数(会污染全局对象)时会将该函数的原型重新赋值并在新原型中增加一个操作那么属性的方法,有继承的意思。但是问题来了,只有在创建第一个实例并且执行到if语句的时候才开始改变原型,这时已经来不及了,第一个实例使用的将会是默认的原型。测试代码如下:
var bbb_proto = bbb.prototype; // 先记录bbb的原型
var b1 = new bbb("red", "liuchen1");
var b2 = new bbb("green", "liuchen2");
console.dir(b1);
console.dir(b2);
console.log(b1.__proto__ === b2.__proto__); // 输出false
bbb.prototype = bbb_proto;
var b3 = new bbb("green", "liuchen3");
console.log(b1.__proto__ === b3.__proto__); // 输出true
写到这里问题就分析完了,那总结一下吧。
总结:改变构造函数原型的时机很重要,动态改变原型要慎重,特别是已经创建了一些实例以后。已经创建的对象不会使用新原型对象。
多说几句,做如下一个有趣的实验(实验在chrome中进行),请大家仔细反复阅读代码。
function a(){} function b(){} // Object.prototype.xxx = '--00--'; // IE这样写 new a().__proto__.__proto__.xxx = "--00--"; // 非IE这样写 console.log(new a().__proto__ === new b().__proto__); //false // IE会打印true,因为 undefined === undefined console.log(new a().__proto__.__proto__ === new b().__proto__.__proto__); //true // IE会报错,测试请删除 console.log(Object.prototype === new a().__proto__.__proto__); //true // IE会报错,测试请删除 console.log(a.prototype instanceof Object); //true console.log(new a().__proto__ instanceof Object); //true // 同样注意IE的问题 console.log(new a() instanceof Object) //true console.log(Object.prototype instanceof Object) //false console.log(a.prototype === b.prototype); //false console.log(new a().__proto__ === a.prototype); //true console.log(typeof(a.prototype)); //object console.log(typeof(Object.prototype)); //object console.log(new a().xxx); //--00-- console.log(new b().xxx); //--00-- console.log(Object.xxx); //--00-- console.log(new Object().xxx); //--00-- console.log(window.xxx); //--00-- console.log(document.xxx); //--00-- console.log(document.head.xxx); //--00-- console.log(document.getElementById("div").xxx); //--00-- //请确保dom节点已经存在 console.log("global", xxx); //global --00-- yyy = "0000"; delete window.yyy; console.log(window.yyy); //undefined写了一些乱其乱七八糟的代码,下面做写说明: