【问题标题】:Returning an Javascript Object's property by Value NOT Reference通过值非引用返回 Javascript 对象的属性
【发布时间】:2010-11-22 19:15:54
【问题描述】:

所以我有一个类 foo,它有一个返回数组 bar 的方法。我有另一个函数调用 foo.getBar 然后过滤数组。当我使用不同的过滤器时,我希望能够始终获得 bar 的原始内容,但 bing 似乎只是创建对 bar 的引用,而不是单独的数组。我试过使用 return this.bar.valueOf();在我的函数 foo 中,仍然无法正常工作。当我从 bing 中删除项目时,它们也会从 bar 中删除。有人请启发我创建一个唯一的数组而不是引用。

function foo(x, y, z){

    this.bar = new Array();
    ...
    this.bar = [ some , stuff , in , bar ];

    this.getBar = function getBar(){
        return this.bar;    
    }
    ...
}

var FooObject = new foo(x,y,z);

function baz(){

    var bing = FooObject.getBar();

    bing.splice(remove some pieces of the array);
}

【问题讨论】:

    标签: javascript arrays object function return-value


    【解决方案1】:

    对于对象,使用克隆方法:

    function cloneObject(source) {
        for (i in source) {
            if (typeof source[i] == 'source') {
                this[i] = new cloneObject(source[i]);
            }
            else {
                this[i] = source[i];
            }
        }
    }
    
    var obj1= {bla:'blabla',foo:'foofoo',etc:'etc'};
    
    var obj2= new cloneObject(obj1);
    

    【讨论】:

      【解决方案2】:

      获取数组副本的最简单(据我所知也是最快)的方法是使用 slice 方法。没有任何参数,它默认为array.slice(0, array.length),所以它会复制整个数组。

      您的 getBar 函数如下所示:

      this.getBar = function getBar(){
          return this.bar.slice();        
      }
      

      请注意,这是一个浅拷贝,因此对数组中对象的任何更改都会影响原始对象(但添加和删除项目不会影响它)。

      【讨论】:

      • 我的数组包含对象,但对象本身不会改变,它们只需要再次添加的能力。例如 [ Object Ford , Object Chevy , Object Toyota , Object BMW ] 我可能会运行 baz 来只显示美国汽车,所以我希望能够从数组中删除 Toyota 和 BMW,然后在剩余的对象上运行一个方法来渲染一些 HTML,但如果过滤器被删除,我希望能够再次对所有数组项运行呈现 HTML 方法。对象本身不会改变,只是从数组的副本中删除。那么这行得通吗?
      • 这似乎有效,感谢大家的及时回复!这是我第一次在 Stack Overflow 上发帖,而且肯定不会是最后一次。
      【解决方案3】:

      不幸的是,javascript 数组和对象总是通过引用传递。如果您保证您的 foo.bar 数组是一维的/不包含数组或对象,

      那么你可以这样做:

      var bing = FooObject.getBar().slice(0);
      

      这将对foo.bar 进行一深复制,从而使您的bing 数组独立于foo.bar 数组。

      否则你将不得不滚动/找到一个深拷贝方法,例如 mootools 中的 $A 函数

      var newArray = $A(oldArray)
      

      【讨论】:

        【解决方案4】:

        返回“克隆”将确保原始数组未受影响。请注意,这样的克隆会很浅。

        function foo(x, y, z){
        
            this.bar = [ some , stuff , in , bar ];
            ...
            this.getBar = function getBar(){
               return this.bar.concat([]);
            }
            ...
        }
        

        【讨论】:

          【解决方案5】:

          你要做的就是像下面这样,传递一个函数作为参数并强制传值;

          function foo(x, y, z) {
              this.bar = ['uno', 'dos', 'tres'];
          }
          foo.prototype.getBar = function() {
              return this.bar;
          }
          ...
          function getBar(fn) {
              return fn();
          }
          ...
          var f = new foo(x, y, z);
          var bing = getBar(f.getBar);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-10-12
            • 2015-09-20
            • 1970-01-01
            相关资源
            最近更新 更多