Попытка получить объект, чтобы идентифицировать его родительский объект, не передавая родительский объект в экземпляр дочернего объекта - PullRequest
2 голосов
/ 14 сентября 2011

У меня проблемы с поиском подробной информации по этому вопросу. Я хотел бы создать экземпляр Bar () внутри Foo () без необходимости передавать указатель на Foo (). Или каким-то образом Bar () узнает, что это потомок Foo (). Это возможно? Или я уже использую достаточный метод?

По сути, я пытаюсь избежать вызова, как:

var bar1 = new Bar(this,someValue);

Ниже приведен пример грубого метода, который я сейчас использую.

function Bar(p,val) {
    var par = p,
        value = val;
    this.__defineGetter__("value", function() {
        return par.dun.value + value;
    });
}

function Dun(val) {
    var value = val;
    this.__defineGetter__("value", function() {
        return value;
    });
}

function Foo() {
    var dun = new Dun(15);
    var bar1 = new Bar(this, 10);
    var bar2 = new Bar(this, 20);
    this.__defineGetter__("dun", function() {
        return dun;
    });
    this.__defineGetter__("bar1", function() {
        return bar1;
    });
    this.__defineGetter__("bar2", function() {
        return bar2;
    });
}
var myFoo = new Foo();
myFoo.bar1.value;

Спасибо.

Ответы [ 3 ]

2 голосов
/ 14 сентября 2011

Нет, это невозможно, так как в JavaScript нет встроенной родительской / дочерней логики.Это просто ссылки на объекты.

Обновление

о, извините, мне кажется, я неправильно понял ваш вопрос.Я задал тот же вопрос некоторое время назад: здесь .То, что вы пытаетесь сделать, это получить объект, который является «этим», в функции, которая вызвала текущую функцию.

Ответ таков: вы не можете сделать это ...

Но вы можете сделать это, используя область действия:

function Dun(val) {
    var value = val;
    this.__defineGetter__("value", function() {
        return value;
    });
}

function Foo() {
    var dun = new Dun(15);
    var bar1 = new Bar(10);
    var bar2 = new Bar(20);
    this.__defineGetter__("dun", function() {
        return dun;
    });
    this.__defineGetter__("bar1", function() {
        return bar1;
    });
    this.__defineGetter__("bar2", function() {
        return bar2;
    });
    function Bar(val) {
        this.__defineGetter__("value", function() {
            return dun.value + val;
        });
    }
}
var myFoo = new Foo();
myFoo.bar1.value;

PS: Не имеет отношения к вашему вопросу, но приятно знать: поскольку

function(val){}

совпадает с

function(){
    var val = arguments[0];
}

вам не нужно создавать новую переменную и передавать ей значение аргументов.Вы можете использовать переменную аргумента напрямую.

1 голос
/ 14 сентября 2011

Нет способа автоматически узнать указатель this вызывающей стороны new. Итак, если вы хотите знать, что это за значение, не передавая его как часть конструктора, вам нужно установить какое-то полуглобальное состояние, которое содержит соответствующую информацию. Вы можете сделать это так:

function Bar(val) {
    var par = Bar.parent(),
        value = val;
    this.__defineGetter__("value", function() {
        return par.dun.value + value;
    });
}

// global methods and state on the Bar function
Bar.createContext = [];
Bar.push = function(o) {Bar.createContext.push(o);}
Bar.pop = function() {Bar.createContext.pop();}
Bar.parent = function() {return(Bar.createContext[Bar.createContext.length - 1]);}

function Dun(val) {
    var value = val;
    this.__defineGetter__("value", function() {
        return value;
    });
}

function Foo() {
    Bar.push(this);               // set global state
    var dun = new Dun(15);
    var bar1 = new Bar(10);       // don't need to pass "this" since it's in the global state
    var bar2 = new Bar(20);
    this.__defineGetter__("dun", function() {
        return dun;
    });
    this.__defineGetter__("bar1", function() {
        return bar1;
    });
    this.__defineGetter__("bar2", function() {
        return bar2;
    });
    Bar.pop();                    // restore global state
}
var myFoo = new Foo();
myFoo.bar1.value;

И вы можете увидеть, как это работает здесь: http://jsfiddle.net/jfriend00/wMgBL/

0 голосов
/ 14 сентября 2011

Вам нужно дать дочернему объекту одно из следующего:

  1. Прямой указатель от одного объекта к другому, как в вашем примере кода.
  2. Уникальная информация о родительском объекте, так что он может определить, что этот родительский косвенно, другими способами.

    Например, вы можете хранить все экземпляры Foo в глобальном объекте реестра (литерале объекта или массиве), через который дочерний объект bar может выполнять поиск. Он будет искать объект с дочерним элементом bar, равным самому себе. 1 Таким образом, тот факт, что это дочерний элемент Foo, является уникальным идентификатором. Если, конечно, один bar не может совместно использоваться несколькими foo с. Тогда ты навеки. :)


1: Недостатком этого является то, что вы храните каждый экземпляр Foo, когда-либо созданный, что означает, что они никогда не будут собирать мусор: у вас будет утечка памяти, что может быть плохо, если ваш среда некоторое время остается на месте (например, приложение node.js).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...