Доступ к родительским объектам при использовании варианта шаблона модуля javascript - PullRequest
1 голос
/ 06 ноября 2011

Привет! Я использую этот вариант шаблона модуля и ищу лучший способ получить доступ к родительскому объекту.Я понимаю, что нет никакого способа узнать, какие родители есть у объекта, поэтому я хочу включить некоторый контекст в конструктор.Я думал, что это будет работать, но это не так, есть идеи?

$(document).ready(function(){ 

    var main = new Main();

});


function Main() {

    var one = 'hello';

    init();

    function init() {
        var data = new Data(this);
        var two = data.load();
        console.log(one+' '+two);
        data.output();
    }

}

function Data(context) {

    // public vars / methods

    var pub = {
        'load' : function() {
            return ('world');
        },
        'output' : function() {
            var one = context.one // <-- what should this be?
            var two = this.load();
            console.log (one+' '+two);
        }
    }

    return pub;

}

Вывод:

hello world
undefined world

1 Ответ

2 голосов
/ 06 ноября 2011

Когда вы вызываете функцию конструктора с оператором new, вы в основном делаете что-то вроде

function Main(){
    var this = //magic new object
               //provided by the runtime

    //your code comes here

    return this;
    //because your Data function returns a value,
    // you never get to this line. Perhaps you should use
    // a regular non-constructor data() function instead?
}

Когда вы объявляете приватную переменную с var, это будет просто простая переменная и ничегоостальное.Если вы хотите добавить что-то к this, вам нужно сделать это явно

this.one = 'hello';

Но это еще не все!this это , а не в лексической области, поэтому функция init получает свой собственный this, который не связан с this извне (это объясняет undefined, который вы получаете).Когда вы хотите использовать this во внутренней функции, вам нужно сделать обходной путь, например:

var that = this;

function init(){
    new Data(that);
}
init();

Тем не менее, на вашем примере я не понимаю, зачем вам нужносделать все это.Я предпочитаю использовать функции конструктора (и new) только тогда, когда это строго необходимо (когда я хочу использовать наследование прототипа).В вашем случае, возможно, вы можете избежать неприятностей с подходом «меньше ОО»?

//main doesn't need to be a class
// this is not Java :)
function main(){

    //just a plain object for the 
    //context. Create a separate class
    //if you really need to...
    var context = {
        one: 'hello'
    };

    var data = new Data(context);
    var two = data.load();
    console.log(one+' '+two);
    data.output();
}
...