admin管理员组

文章数量:1287145

So I have a class foo that has a method which returns an array bar. I have another function that calls foo.getBar and then filters the array. I want to be able to always get the original contents of bar when I use a different filter, but bing seems to be just creating a reference to bar, not a separate array. I have tried using return this.bar.valueOf(); in my function foo, still not working. When I remove items from bing they are also removed from bar. Someone please enlighten me on creating a unique array instead of a reference.

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);
}

So I have a class foo that has a method which returns an array bar. I have another function that calls foo.getBar and then filters the array. I want to be able to always get the original contents of bar when I use a different filter, but bing seems to be just creating a reference to bar, not a separate array. I have tried using return this.bar.valueOf(); in my function foo, still not working. When I remove items from bing they are also removed from bar. Someone please enlighten me on creating a unique array instead of a reference.

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);
}
Share Improve this question asked Aug 25, 2009 at 21:39 JesseJesse 3071 gold badge3 silver badges9 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 5

The easiest (and as far as I know, fastest) way to get a copy of an array is to use the slice method. Without any arguments, it defaults to array.slice(0, array.length), so it will copy the entire array.

Your getBar function would look like this:

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

Note that this is a shallow copy, so any changes to the objects in the array will affect the original (adding and removing items won't affect it though).

For objects, use the clone method:

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);

What you'll have to do is something like the following, passing a function as a parameter and force a pass-by-value;

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);

Returning a "clone" will make sure original array is untouched. Note that such clone will be shallow.

function foo(x, y, z){

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

Unfortunately javascript arrays and objects are always passed by reference. If you are guaranteed that your foo.bar array is 1-dimensional/contains no arrays or objects,

Then you can do:

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

Which will do a 1-deep copy of foo.bar, resulting in your bing array being independent of the foo.bar array.

Otherwise you'll have to roll/find a deep copy method, such as the $A function in mootools

var newArray = $A(oldArray)

本文标签: arraysReturning an Javascript Object39s property by Value NOT ReferenceStack Overflow