Доступ к родительскому родительскому объекту из объекта javascript
Что-то вроде
var life= {
users : {
guys : function(){ this.SOMETHING.mameAndDestroy(this.girls); },
girls : function(){ this.SOMETHING.kiss(this.boys); },
},
mameAndDestroy : function(group){ },
kiss : function(group){ }
};
this.SOMETHING - это то, что я представляю, формат, но может и не быть. Что будет делать шаг назад к родительскому объекту?
Ответы
Ответ 1
JavaScript не предлагает эту функцию изначально. И я сомневаюсь, что вы даже можете создать такой тип функциональности. Например:
var Bobby = {name: "Bobby"};
var Dad = {name: "Dad", children: [ Bobby ]};
var Mom = {name: "Mom", children: [ Bobby ]};
Кем принадлежит Бобби?
Ответ 2
Я просто добавил в первую функцию
parentThis = this;
и используйте parentThis в подфункции. Зачем? Потому что в JavaScript объекты мягкие. Новый член может быть добавлен к мягкому объекту простым назначением (не таким, как Java, где классические объекты сложны. Единственный способ добавить нового участника к жесткому объекту - создать новый класс). Подробнее об этом здесь: http://www.crockford.com/javascript/inheritance.html
А также в конце вам не нужно убивать или уничтожать объект. Почему я нашел здесь: http://bytes.com/topic/javascript/answers/152552-javascript-destroy-object
Надеюсь, что это поможет
Ответ 3
В этом случае вы можете использовать life
для ссылки на родительский объект. Или вы можете сохранить ссылку на life
в объекте users. В языке не может быть установлен фиксированный parent
, поскольку пользователи - это просто ссылка на объект, и могут быть другие ссылки...
var death = { residents : life.users };
life.users.smallFurryCreaturesFromAlphaCentauri = { exist : function() {} };
// death.residents.smallFurryCreaturesFromAlphaCentauri now exists
// - because life.users references the same object as death.residents!
Вам может показаться полезным использовать что-то вроде этого:
function addChild(ob, childName, childOb)
{
ob[childName] = childOb;
childOb.parent = ob;
}
var life= {
mameAndDestroy : function(group){ },
kiss : function(group){ }
};
addChild(life, 'users', {
guys : function(){ this.parent.mameAndDestroy(this.girls); },
girls : function(){ this.parent.kiss(this.boys); },
});
// life.users.parent now exists and points to life
Ответ 4
Если я правильно читаю ваш вопрос, объекты вообще не зависят от того, где они содержатся. Они не знают, кто их родители. Чтобы найти эту информацию, вам необходимо проанализировать родительскую структуру данных. У DOM есть способы сделать это для нас, когда вы говорите об объектах элементов в документе, но похоже, что вы говорите о ванильных объектах.
Ответ 5
О вызове:
Вы можете решить эту проблему, используя .call()
, который:
- необходимо вызвать функцию
addName.call()
- вы передаете ему объект того, кем вы хотите быть "this"
addName.call({"name" : 'angela'});
- вы можете передать дополнительные аргументы, которые могут использоваться в функции, которую она вызывается в
addName.call({"name": "angela"}, true);
, где возможно addName
принимает аргумент boolean append
.
Использовать вызов:
Для этой конкретной задачи мы можем передать "родительский" объект через call
, чтобы переопределить this
, обычно присутствующий в дочернем объекте.
Посмотрите на нашу проблему в первую очередь
var app = {
init: function() {
var _this = this; // so we can access the app object in other functions
$('#thingy').click(function(){
alert(_this.options.thingy());
});
$('#another').click(function(){
alert(_this.options.getAnother());
});
},
options: {
thingy: function() {
// PROBLEM: the this here refers to options
return this.getThingy();
},
getAnother: function() {
// PROBLEM 2: we want the this here to refer to options,
// but thingy will need the parent object
return 'another ' + this.thingy();
},
},
getThingy: function() {
return 'thingy';
}
};
Теперь, здесь решение использует вызов
И JSFIDDLE, чтобы увидеть, как он работает.
var app = {
init: function() {
var _this = this; // so we can access the app object in other functions
$('#thingy').click(function(){
// SOLUTION: use call to pass _this as the 'this' used by thingy
alert(_this.options.thingy.call(_this));
});
$('#another').click(function(){
// SOLUTION 2: Use call to pass parent all the way through
alert(_this.options.getAnother.call(_this));
});
},
options: {
thingy: function() {
// SOLUTION in action, the this is the app object, not options.
return this.getThingy();
},
getAnother: function() {
// SOLUTION 2 in action, we can still access the options
// AND pass through the app object to the thingy method.
return 'another ' + this.options.thingy.call(this);
},
},
getThingy: function() {
return 'thingy';
}
};
В заключение
Вы можете использовать .call()
всякий раз, когда вы используете метод для свойства вашего основного объекта: app.options.someFunction(arg)
должен всегда вызываться с помощью .call
- app.options.someFunction.call(this, arg);
- таким образом вы можете гарантировать, что у вас всегда будет доступ к каждой части объекта. Это может дать вам доступ к другим методам собственности, таким как app.helpers.anotherFunction()
.
Хорошая идея в somefunction
, сохраните this
в переменной _parentThis
, чтобы она была очевидна, что отражает this
.
Ответ 6
Здесь вы идете:
var life={
users:{
guys:function(){ life.mameAndDestroy(life.users.girls); },
girls:function(){ life.kiss(life.users.guys); }
},
mameAndDestroy : function(group){
alert("mameAndDestroy");
group();
},
kiss : function(group){
alert("kiss");
//could call group() here, but would result in infinite loop
}
};
life.users.guys();
life.users.girls();
Кроме того, убедитесь, что у вас нет запятой после определения "девочки". Это приведет к сбою script в IE (в любое время, когда у вас есть запятая после последнего элемента в массиве в IE, она умирает).
Посмотрите, как он работает
Ответ 7
Я использовал что-то похожее на одноэлементный шаблон:
function myclass() = {
var instance = this;
this.Days = function() {
var days = ["Piątek", "Sobota", "Niedziela"];
return days;
}
this.EventTime = function(day, hours, minutes) {
this.Day = instance.Days()[day];
this.Hours = hours;
this.minutes = minutes;
this.TotalMinutes = day*24*60 + 60*hours + minutes;
}
}
Ответ 8
Как говорили другие, невозможно напрямую искать родителя из вложенного ребенка. Все предлагаемые решения предлагают различные способы обращения к родительскому объекту или родительской области с помощью явного имени переменной.
Однако прямое перемещение до родительского объекта возможно, если вы используете рекурсивные ES6 Proxies для родительского объекта.
Я написал библиотеку с именем ObservableSlim, которая, среди прочего, позволяет вам переходить от дочернего объекта к родительскому.
Вот простой пример (jsFiddle demo):
var test = {"hello":{"foo":{"bar":"world"}}};
var proxy = ObservableSlim.create(test, true, function() { return false });
function traverseUp(childObj) {
console.log(JSON.stringify(childObj.__getParent())); // returns test.hello: {"foo":{"bar":"world"}}
console.log(childObj.__getParent(2)); // attempts to traverse up two levels, returns undefined because test.hello does not have a parent object
};
traverseUp(proxy.hello.foo);
Ответ 9
Я сделал что-то подобное, и это работает как шарм.
Simple.
P.S. Объект больше, но я только что разместил соответствующую часть.
var exScript = (function (undefined) {
function exScript() {
this.logInfo = [];
var that = this;
this.logInfo.push = function(e) {
that.logInfo[that.logInfo.length] = e;
console.log(e);
};
}
})();
Ответ 10
В следующем коде вы можете получить доступ к родительскому объекту объекта:
var Users = function(parent) {
this.parent = parent;
};
Users.prototype.guys = function(){
this.parent.nameAndDestroy(['test-name-and-destroy']);
};
Users.prototype.girls = function(){
this.parent.kiss(['test-kiss']);
};
var list = {
users : function() {
return new Users(this);
},
nameAndDestroy : function(group){ console.log(group); },
kiss : function(group){ console.log(group); }
};
list.users().guys(); // should output ["test-name-and-destroy"]
list.users().girls(); // should output ["test-kiss"]
Я бы порекомендовал вам прочитать о javascript Objects, чтобы узнать, как вы можете работать с объектами, это очень помогло мне. Я даже узнал о функциях, которые я даже не знал, что они существуют.
Ответ 11
Если вы хотите получить ключ всех родителей node в литеральном объекте ({}
), вы можете сделать это:
(function ($) {
"use strict";
$.defineProperties($, {
parentKeys: {
value: function (object) {
var
traces = [],
queue = [{trace: [], node: object}],
block = function () {
var
node,
nodeKeys,
trace;
// clean the queue
queue = [];
return function (map) {
node = map.node;
nodeKeys = Object.keys(node);
nodeKeys.forEach(function (nodeKey) {
if (typeof node[nodeKey] == "object") {
trace = map.trace.concat(nodeKey);
// put on queue
queue.push({trace: trace, node: node[nodeKey]});
// traces.unshift(trace);
traces.push(trace);
}
});
};
};
while(true) {
if (queue.length) {
queue.forEach(block());
} else {
break;
}
}
return traces;
},
writable: true
}
});
})(Object);
Этот алгоритм использует концепцию FIFO
для итерации графиков с использованием метода BFS
. Этот код расширяет класс Object
, добавляя статический метод parentKeys
, который ожидает в качестве параметра literal Object
(хеш-таблица - ассоциативный массив...) Javacript.
Надеюсь, я помог.