#javascript #reference
#javascript #ссылка
Вопрос:
Мне нужно перебирать вложенные классы объектов и извлекать их свойства из объекта. Но изменение значений свойств внутри объектов не изменяет значения в переменной, содержащей корневой объект этих объектов. Когда я проверяю изнутри объектов, новые значения применяются правильно.
Однако, если я добавлю новые свойства вместо изменения существующих свойств, я смогу получить доступ к новым.
var OO = function(o, parent){
this.parent = parent || null;
this.init(o);
return this;
};
OO.prototype = {
init: function(o){
this.obj = typeof o === 'object' ? new OO(o.name, this) : o;
this.type = typeof o === 'object' ? 'object' : 'string';
if( typeof o === 'string' ){
this.change();
console.log(this.parent); // Here top-level oo object holds values called in change() function. I want the variable ( oo_var ) holding this top-level oo to have same property values too.
this.add();
}
},
change: function(){
this.parent.obj = 'Orange'; // Holds {} before changing
this.parent.type = 'string'; // 'object' before changing
},
add: function(){
this.parent.another_obj = 'Another';
this.parent.another_type = 'another string';
}
};
var oo_var = new OO({name: 'Apple'}); // This var doesn't refresh the obj amp; type property values applied in change() function. But has properties added in add() function.
У меня много уровней вложенных объектов с братьями и сестрами на каждом уровне.
Комментарии:
1. Ваш
init
метод выполняет запись вoo_var.obj
и.type
после создания дочернего объекта — и после того, как он.change()
их разделяет.2. Чего вы действительно хотите? И почему создание объекта должно изменить его родительский элемент?
3. @Bergi, я меняю родительские свойства с дочерних. Когда я смотрю после их изменения (консоль. войдите в change() ), это выглядит нормально. Но когда я смотрю извне (консоль. log после var oo_var = …) родительский элемент по-прежнему имеет начальные значения. См. jsfiddle
4. Я хочу иметь возможность изменять значения свойств родительских / дедушкиных свойств у дочерних элементов и получать к ним доступ
oo_var
.5. Вы уже можете получить доступ к родительским элементам и изменить их из дочерних элементов. Ваша проблема в том, что ваша родительская инициализация происходит после инициализации вашего дочернего элемента, поэтому «измененные» значения будут перезаписаны «начальными» значениями. Ваш
init
метод не должен вызыватьchange
oradd
. Зачем это нужно?
Ответ №1:
Конструктор должен выполнять только создание, а не изменять состояние чего-либо. Ему не нужно вызывать init
метод, и он определенно не должен вызывать (даже косвенно) change
метод.
Сделайте это
function OO(o, parent) {
this.parent = parent || null;
this.type = typeof o;
this.obj = this.type === 'object' ? new OO(o.name, this) : o;
}
OO.prototype.change = function() {
this.parent.obj = 'Orange'; // Holds {} before changing
this.parent.type = 'string'; // 'object' before changing
};
OO.prototype.add = function(){
this.parent.another_obj = 'Another';
this.parent.another_type = 'another string';
};
var oo_var = new OO({name: 'Apple'});
console.dir(oo_var);
oo_var.obj.change();
oo_var.obj.add();
console.dir(oo_var);
Также немного странно (если не неправильно), чтобы дочерний элемент менял родительский элемент, а не сам родительский элемент.
Если вы не хотите вызывать методы самостоятельно, вы можете использовать для этого метод:
OO.prototype.init = function() {
if (this.type === 'object' ) {
this.obj.init();
} else if (this.type === 'string') {
this.change();
this.add();
}
};
var oo_var = new OO({name: 'Apple'});
console.dir(oo_var);
oo_var.init();
console.dir(oo_var);