码迷,mamicode.com
首页 > 其他好文 > 详细

原型陷阱

时间:2016-09-17 23:34:41      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

 处理原型问题时,我们需要特别注意一下两种行为。
1、当我们对原型对象执行完全替换时,可能会触发原型链中的某种异常
2、prototype。constructor属性是不可靠的
下面,我们来新建一个简单的构造器函数,并用它再创建两个对象;
function Dog() {
this.tail = true;
}
var benji = new Dog();
var rusty = new Dog();

/*
* 即便在benji和rusty对象创建之后,我们也依然能为Dog();的原型添加属性,并且在属性被添加之前就已经存在的对象
* 也可以随时访问这些新属性。现在,让我们放一个say()方法进去*/
Dog.prototype.say = function () {
return ‘Woof‘;
};
/*这样,上面的两个对象都可以访问该新方法了;*/
console.log(benji.say());//Woof
console.log(rusty.say());//Woof
/*检查一下这些对象的构造器函数,就会发现一切正常*/
console.log(benji.constructor === Dog); //true
console.log(rusty.constructor === Dog); //true

/*现在我们用一个新对象完全覆盖掉原有的原型对象;*/
Dog.prototype = {
paws : 4,
hair : true
};

/*事实证明,这会使原有对象不能访问原型的新增属性,他们依然通过那个神秘的链接与原有的原型对象保持联系*/
console.log(typeof benji.paws); //undefined
console.log(benji.say()); //Woof
console.log(typeof benji.__proto__.say); //function
console.log(typeof benji.__proto__.paws); //undefined

/*而我们之后创建的所有对象使用的都是被更新后的prototype对象.*/

var lucy = new Dog();
// console.log(lucy.say());//Uncaught TypeError: lucy.say is not a function
console.log(lucy.paws); //4

/*并且,其秘密链接_proto_也指向了新的prototype对象;*/
console.log(typeof lucy.__proto__.say); //undefined
console.log(typeof lucy.__proto__.paws); //number

/*但这时候,新对象的constructor属性就不能保持正确了,原本原本应该是Dog();的引用只想了Object.*/
console.log(lucy.constructor); //function Object() { [native code] }
console.log(benji.constructor);/*
Dog() {
this.tail = true;
}
*/

/*当然,我们可以通过重新设置constructor属性来解决上述所有的异常行为*/
function Dog(){}
Dog.prototype = {};
console.log(new Dog().constructor ===Dog);//false


Dog.prototype.constructor = Dog;
console.log(new Dog().constructor === Dog);//true

/*
* 声明:
* 本文借鉴JavaScript面向对象编程指南(第二版)
* */

原型陷阱

标签:

原文地址:http://www.cnblogs.com/ass233/p/5879922.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!