如何在使用extend克隆时更新原始文件

时间:2015-01-08 01:48:42

标签: javascript jquery clone

我正在尝试使用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变量是私有的(并且有很多很好的理由让它保持这样)所以这意味着你不能在实例之外设置它。

2 个答案:

答案 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的克隆方法替换了我的问题。