【发布时间】:2015-01-08 01:48:42
【问题描述】:
我正在尝试使用 jquery 扩展方法克隆一些对象。但是,在克隆我的对象后,我意识到克隆对象的某些方法正在修改原始对象的值,所以我认为两个对象的属性可能指向同一个变量。
在运行了一些测试之后,我发现我的克隆对象的属性被正确复制了……包括本地的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
extend 方法的行为确实有意义...但是是否有一种通用 方法来确保self 变量引用新的克隆对象?泛型是指self 变量可能有不同的名称(即_this 等),并且我想避免为每个类添加自定义方法只是为了更新self 变量。
您还应该记住,self 变量是私有的(有很多很好的理由保留它)所以这意味着您不能在实例之外设置它。
【问题讨论】:
-
extend扩展对象,它不会创建新实例。我认为唯一(也是正确的)方法是创建一个新动物,而不是复制旧动物。 -
或者,创建一个使用正确上下文更改属性的方法 -> jsfiddle.net/1572gy9o
-
确实...以动物为原型并从那里创建新实例更有意义。您可以根据需要制作子级别。通过扩展将狗变成猫似乎有点奇怪。
-
@adeneo
extend仍然是我们谈论克隆对象时的参考方法,即使它不是主要目的。创建一个新实例将是一个易于实现的解决方案(在我的情况下),但我脑海中总是有一个声音在说“你这个懒惰的程序员,找到一个通用的解决方案!”。 -
但创建新动物的通用且正确的解决方案是创建
Animal类的新实例,而不是克隆狗,可以这么说。$.extend不是类实例的引用,它通常不用于。
标签: javascript jquery clone