3

我已经阅读了几个小时,似乎找不到适合我需要的答案。由于代码的大小,我现在不想更改结构。如果可能的话,我正在尝试在我已经建立的结构内找到一个可行的解决方案。

首先,这是我的对象字面量结构的一个非常简化的模型:

NS = 
{
    x: undefined,

    button: undefined,

    fn: 
    {
        root: undefined,

        doSomething: function () 
        {
            var root = this.root,
                x = root.x;       // exception occurs here

            // do something with x
        }
    },

    init: function () 
    {
        var self = this,
            x = self.x,
            button = self.button,
            fn = self.fn,
            fn.root = self;

        x = $("#x");
        button = $("#button");    

        button.on("click", fn.doSomething);
    }
};

我知道看起来下面的声明init()并不是真正需要的,但是命名空间可能会变得相当长,所以我喜欢这样缩短它们。在我遇到这个障碍之前,这几乎在所有情况下都对我很有效。我知道我可以完全限定所有内容并且它应该可以工作,但由于前面提到的长命名空间,我真的不想这样做。

我的问题是,当从另一个属性的函数中访问它时,我的根属性x在函数中设置后没有保留其值。init()你可以console.log(this.x)init()函数内部,它就在那里。但是,当您单击按钮并且 onClick 函数尝试声明x = root.x它时会抛出:

未捕获的类型错误:无法读取未定义的属性“x”


更新:

即使在调用处理程序之前添加未定义的console.log()节目:fn.root.x

init: function () 
{
    var self = this,
        x = self.x,
        button = self.button,
        fn = self.fn,
        fn.root = self;

    x = $("#x");

    console.log(x); // this shows the object
    console.log(fn.root.x); // this throws the undefined exception

    button = $("#button");    
    button.on("click", fn.doSomething);
}
4

2 回答 2

3

当 doSomething 作为事件处理程序调用时,this将是函数内部的事件目标。所以this.root将是未定义的,并且未定义没有任何属性,因此root.x会引发错误。

一种解决方案是固定thiswith的值$.proxy

button.on("click", $.proxy(fn.doSomething, self));
于 2013-04-23T02:56:05.067 回答
0

实际上,JS 对象和数组是通过引用传递的。在您的示例中,如果 x 是一个对象而不是undefined

NS = {
    x: {},
    button: undefined,
    // etc
};

然后在你的init方法中你可以做这样的事情,它会起作用:

init: function(){
    var self = this,
        x = self.x;

    x.foo = 'foo!';
    console.log(self.x.foo);  // Logs 'foo!'
}

但是,在您的示例中,当您分配时,您x = $('#x')实际上只是将此本地 x 变量的引用更改为新创建的 jQuery 对象。为了使您的示例正常工作,您需要做的是使两个变量都引用同一个对象:

init: function(){
    var self = this,
        x = self.x = $('#x');

    x.on('click', function(){
        console.log('foo!');
    });

    self.x.trigger('click');  // Logs 'foo!'
}
于 2013-05-13T19:29:22.970 回答