简体   繁体   中英

Returning an Javascript Object's property by Value NOT Reference

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

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM