Как в JavaScript передать значение объекта, а не ссылку на объект?

420
31 июля 2017, 14:57

Имеется функция (класс) в которую передаю произвольный объект для хранения настроек.

    function MyClass(cfg) {
        this._config = cfg;
    }
    MyClass.prototype.cfg = function(key) {
        if (typeof key === 'undefined') return this._config;
        if (typeof this._config[key] === "undefined") return null;
        return this._config[key];
    };
    let config = {
        log_name: "app.new_content.post_source",
        path: [
            {
                url: "/fh/new_content/",
                title: "Новый контент"
            }
        ],
        list_filter_default: {
            trash: 0
        }
    };
    const my_class = new MyClass(config);
    let list_filter_default = my_class.cfg("list_filter_default");
    list_filter_default.trash = 1;
    console.log(my_class);
    //...
    //    list_filter_default: {
    //        trash: 1
    //    }
    //...

Как переписать функцию cfg(), чтобы дальнейшее изменение переменных не влекло за собой изменение свойства this._config?

Answer 1

В этой ситуации вижу два варианта решения вопроса. Примеры будут упрощенны, однако, надеюсь, вы поймете суть

Вариант 1: красивый: заморозка
refer to @Grundy - заморозится только первый уровень!

const config = { 
  ACCESSS: true 
}; 
function MyClass (cfg) { 
  return Object.freeze(cfg); 
} 
 
const cfg = MyClass(config); 
cfg.ACCESS = false; 
cfg.TEST = false; 
// nothing changed 
console.log(cfg); 
console.log(config);

Вариант 2: как мы любим

const config = { 
  ACCESSS: true 
}; 
 
function MyClass(cfg) { 
  return JSON.parse(JSON.stringify(config)); 
} 
 
const cfg = MyClass(config); 
cfg.ACCESS = false; 
// only parent didn't change 
console.log(cfg); 
console.log(config);

Answer 2

Как по мне, так есть и 3 вариант - вернуть новый объект при помощи Object.assign({},this._config[key]) или спред-оператора .... Таким образом исходный объект останется неизменным.

function MyClass(cfg) {
        this._config = cfg;
    }
    MyClass.prototype.cfg = function(key) {
        if (typeof key === 'undefined') return this._config;
        if (typeof this._config[key] === "undefined") return null;
        return Object.assign({},this._config[key]);
    };
    let config = {
        log_name: "app.new_content.post_source",
        path: [
            {
                url: "/fh/new_content/",
                title: "Новый контент"
            }
        ],
        list_filter_default: {
            trash: 0
        }
    };
    const my_class = new MyClass(config);
    let list_filter_default = my_class.cfg("list_filter_default");
    list_filter_default.trash = 1;
    console.log(my_class);
//...
//    list_filter_default: {
//        trash: 0
//    }
    console.log(list_filter_default);
//   { trash: 1 }
READ ALSO
Кастомные названия DataTables

Кастомные названия DataTables

Хочу изменить текст "Previous" и "Next" на свой вариантИсходя из документации раз, два я нашел:

305
Дебаг приложения create-react-app

Дебаг приложения create-react-app

Я создал реакт приложение через react-create-appИ в одном из компонентов допустил ошибку

205
Как сделать numeric из string?

Как сделать numeric из string?

Как из вот этого "2" сделать numeric?

324
JSON. Денежные курсы

JSON. Денежные курсы

У меня есть такой JSON ответ:

305