Разные способы передачи переменной по ссылке

Вопросы и ответы

Я хочу передать переменную в функцию и чтобы функция изменила её значение.

Я знаю, что могу сделать это с помощью объекта, но интересно, есть ли другой способ, о котором я не подумал.

Вот что я хочу сделать, но, конечно, это не работает так, как я хочу:

function test1(vari) {
    vari = 2;
}
var myvar1 = 1;
test1(myvar1);
console.log(myvar1);

Это работает, но я не действительно хочу, чтобы все переменные были объектами:

function test2(vari) {
    vari.val = 2;
}
var myvar2 = { val: 1 };
test2(myvar2);
console.log(myvar2.val);

Это тоже работает, но это неприемлемое решение:

function test3(vari) {
    eval(vari + ' = 2;');
}
var myvar3 = 1;
test3('myvar3');
console.log(myvar3);

Существует ли более хороший вариант, чем эти?

Это может быть не то, что вы ищете, но возможно, попробуйте что-то вроде:

function test1(vari) {
    return vari += 2;
}

var myvar1 = test1(myvar1);

console.log(myvar1);

Ответ

Вопрос, с которым вы столкнулись, касается передачи переменных по ссылке, чтобы функция могла изменять их значение. В некоторых языках программирования есть возможность напрямую изменять значения переменных, переданных в функции, но в JavaScript это не так просто, поскольку примитивные типы (например, числа и строки) передаются по значению, а не по ссылке. Рассмотрим несколько подходов для достижения желаемого результата.

1. Использование объектов

Вы уже упомянули, что можете обернуть переменную в объект, и это действительно один из самых простых способов передать "по ссылке". Например:

function test(vari) {
    vari.value = 2;
}

let myvar = { value: 1 };
test(myvar);
console.log(myvar.value); // 2

2. Использование массива

Другой подход — использовать массив. Массивы, как и объекты, передаются по ссылке.

function test(vari) {
    vari[0] = 2;
}

let myvar = [1]; // массив с одним элементом
test(myvar);
console.log(myvar[0]); // 2

3. Возврат значения

Если вам не хочется использовать объекты или массивы, вы можете вернуть новое значение из функции, как вы уже упомянули в своем вопросе:

function test(vari) {
    return vari + 1; // например, увеличиваем на 1
}

let myvar = 1;
myvar = test(myvar);
console.log(myvar); // 2

4. Использование функции более высокого порядка

Вы можете создать обертку, которая позволит вам изменять переменные.

function modifyVar(obj) {
    return function(newValue) {
        obj.value = newValue;
    };
}

let myvar = { value: 1 };
let setMyVar = modifyVar(myvar);
setMyVar(2);
console.log(myvar.value); // 2

5. Использование Proxy

Если вы хотите более сложное управление, вы также можете использовать Proxy для перехвата изменений:

let handler = {
    set(target, property, value) {
        console.log(`${property} изменено на ${value}`);
        target[property] = value;
        return true;
    }
};

let myvar = new Proxy({ value: 1 }, handler);
myvar.value = 2; // "value изменено на 2"
console.log(myvar.value); // 2

Заключение

Каждый из приведенных выше методов имеет свои преимущества и недостатки. Выбор метода зависит от ваших конкретных потребностей и контекста вашего кода. В большинстве случаев, если вам нужно изменять значения, имеет смысл использовать объекты или массивы. Если ваши данные имеют простой тип, возврат значения из функции — это элегантное решение, которое также легко читается и поддерживается.

Оцените материал
Добавить комментарий

Капча загружается...