ссылки на нужные объекты в функциях пространства имен - PullRequest
1 голос
/ 08 апреля 2010

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

Здесь нет проблем:

obj.test = function() {
  // this == obj
}

Но меня сбивают с толку, когда я называю пространство имен:

obj.namespace.test = function() {
  // this == namespace
}

В последнем примере я знаю this ссылки namespace, но я хочу сослаться obj. Как я могу это сделать?

Ответы [ 2 ]

1 голос
/ 08 апреля 2010

Другие сделали несколько хороших предложений.

Я просто хотел добавить, что вы также можете сделать пространство имен функцией, которая будет возвращать объект с переменной, указывающей на obj и любые другие функции-члены, которые вы хотите.

Пример:

    // Note that "namespace" is a reserved word in JS for some reason,
    //  so you can't use it as a variable/function/etc name.
    var myNamespace = function myNamespace(){
        var that = this;

        var test = function test(){
            //in here use this.that to point to obj
            alert(this.that.name);
        };

        return {that: that, test: test};
    };

    // Then create the obj:
    var obj = { name: "Mr. Ahb Jeckt", myNamespace: myNamespace};

    // Then you can just call the "namespace" and member function like this:
    obj.myNamespace().test();


    //Or, "initialize" the namespace and call it like so:
    obj.myNamespace = obj.myNamespace();
    obj.myNamespace.test();

    obj.name = "Mrs Ahb Jeckt";
    obj.myNamespace.test();

Таким образом, в самом «пространстве имен» нет жестко закодированных ссылок на obj, и я думаю, что он довольно чистый.

Это также работает, если obj является "классом"; просто сделайте obj конструктором вместо литерала объекта:

// Then create the obj:
var obj = function (name){
    this.name = name || "unnamed";
    this.myNamespace = myNamespace;

    // Initialize the namespace, we can leave this out and just reference
    //    obj.myNamespace() each time as well

    this.myNamespace = this.myNamespace();
};

// Then you can just call the "namespace" and member function like this:

var myObj = new obj("Mr Ahb Jeckt");
myObj.myNamespace.test();

var myObj2 = new obj("Mrs Ahb Jeckt");
myObj2.myNamespace.test();
1 голос
/ 08 апреля 2010

Простого ответа нет, но у вас есть несколько вариантов:

obj.namespace.test = function () {
  return (function () {
     // this == obj
  }).apply(obj, Array.prototype.slice.call(arguments));
};

Возвращает функцию, связанную с obj. К сожалению, если obj переназначен, это не сработает, потому что это реальная ссылка. Это более надежно:

obj.namespace.test = (function (obj) {
   return function () {
     return (function () {
        // this == obj
     }).apply(obj, Array.prototype.slice.call(arguments));
   };
}(obj));

Как видите, ни один из них не очень чистый. Вы можете спросить себя, почему вы зависите от this для начала. Использование обычной ссылки на obj, очевидно, является наиболее простым подходом.

...