Возврат свойства объекта Javascript по значению NOT Reference - PullRequest
3 голосов
/ 26 августа 2009

Итак, у меня есть класс foo, у которого есть метод, который возвращает строку массива. У меня есть другая функция, которая вызывает foo.getBar, а затем фильтрует массив. Я хочу всегда иметь возможность получать исходное содержимое bar, когда использую другой фильтр, но bing, похоже, просто создает ссылку на bar, а не отдельный массив. Я попытался с помощью return this.bar.valueOf (); в моей функции foo, до сих пор не работает. Когда я удаляю предметы из Bing, они также удаляются из бара. Кто-нибудь, пожалуйста, сообщите мне о создании уникального массива вместо ссылки.

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

Ответы [ 5 ]

5 голосов
/ 26 августа 2009

Самый простой (и, насколько я знаю, самый быстрый) способ получить копию массива - это использовать метод среза. Без аргументов по умолчанию array.slice(0, array.length), поэтому будет скопирован весь массив.

Ваша функция getBar будет выглядеть так:

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

Обратите внимание, что это мелкая копия, поэтому любые изменения объектов в массиве будут влиять на оригинал (хотя добавление и удаление элементов не будут влиять на него).

2 голосов
/ 21 декабря 2011

Для объектов используйте метод клонирования:

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);
0 голосов
/ 26 августа 2009

Возврат клона гарантирует, что исходный массив не будет затронут Обратите внимание, что такой клон будет мелким.

function foo(x, y, z){

    this.bar = [ some , stuff , in , bar ];
    ...
    this.getBar = function getBar(){
       return this.bar.concat([]);
    }
    ...
}
0 голосов
/ 26 августа 2009

К сожалению, массивы и объекты JavaScript всегда передаются по ссылке. Если вам гарантировано, что ваш массив foo.bar является одномерным / не содержит массивов или объектов,

Тогда вы можете сделать:

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

Что сделает копию глубиной 1 foo.bar, в результате чего ваш массив bing будет независим от массива foo.bar.

В противном случае вам придется свернуть / найти метод глубокого копирования, такой как функция $ A в mootools

var newArray = $A(oldArray)
0 голосов
/ 26 августа 2009

То, что вам нужно сделать, это что-то вроде следующего, передавая функцию в качестве параметра и принудительно передавая по значению;

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