我正在尝试使用jquery extend方法克隆一些对象。但是,在克隆我的对象之后,我意识到克隆对象的某些方法正在修改原始对象的值,所以我认为两个对象属性都可能指向同一个变量。
运行一些测试之后,我发现克隆对象的属性被正确复制了......包括本地self
变量(用于保存对原始this
的引用类实例)。由于克隆的self
仍然指向原始实例,因此引用该变量的方法的目标是原始实例的属性,而不是它自己的实例:
var Animal = function() {
var self = this;
this.sound = "";
this.talk = function(){
alert(self.sound);
};
};
var dog = new Animal();
dog.sound = "Woof";
dog.talk(); //Woof as expected
var cat = $.extend(true, {}, dog);
cat.sound = "Meow";
cat.talk(); //Woof... but Meow was expected
扩展方法行为确实有意义......但是有一种泛型方法可以确保self
变量引用新的克隆对象吗?通用,我的意思是self
变量可能有不同的名称(即_this等),我想避免为每个类添加自定义方法只是为了更新self
变量。 / p>
你还应该记住self
变量是私有的(并且有很多很好的理由让它保持这样)所以这意味着你不能在实例之外设置它。
答案 0 :(得分:3)
事实上,对于此用例,您不需要var self = this
构造。
在这里做了一个小测试:http://jsfiddle.net/quwdeafd/
看一下this
的范围。
那不是你想要的吗?
var Animal = function() {
this.sound = "";
this.talk = function(){
console.log(this); //Logs Animal the first time, object the second
console.log(this.sound); //Logs Woof and meow
};
};
var dog = new Animal();
dog.sound = "Woof";
dog.talk();
var cat = $.extend(true, {}, dog);
cat.sound = "Meow";
cat.talk();
小注释:通常将此方法放在对象的原型上是自定义的:
Animal.prototype.talk = function(){
console.log(this);
console.log(this.sound);
};
因为它使该方法立即可用而无需在每个实例化时进行初始化。
答案 1 :(得分:1)
正如阿德内诺指出的那样,问题出现在另一个层面。即使extend
通常被称为克隆方法,也不是为了这个目的。这个问题中提到的问题就是一个很好的例子。
为了记录,我停止使用extend
方法进行克隆,我用一个取自this SO answer的克隆方法替换了我的问题。