对象文字中的范围

时间:2010-09-10 12:47:07

标签: javascript jquery scope

我将从一个示例代码段开始:

self.addwidget({
    box:    ns.box({                        
                text:       'Foobar',
                fromTop:    ~~(Math.random()*window.innerHeight),
                fromLeft:   ~~(Math.random()*window.innerWidth),
                toTop:      240,
                toLeft:     40,
                css:        'foobar',
                easing:     'easeOutCirc',
                duration:   2000,
                events:     {
                    mousedown:      function(e){
                        e.target.position = {x: e.pageX, y: e.pageY};
                    },
                    mouseup:        function(e){
                        // "this" should reference be "box"                                     
                    }
                }
    }),
    delay:  3000
});

简短说明
ns.box()将对象作为参数并创建新的jQuery object。它使用jQuery.extend()events属性对象与jQuery constructor $('<elem/>', {});合并 之后,ns.box()返回一个包含一些方法的新对象 -

我想要达成的目标是访问propertys / methods中的event handlersbox.somemethod。当然,此时我无法访问box,因为此时我无法引用外部jQuery.proxy()属性。因此,我尝试将范围从this更改为this.somemethod,但没有成功。
即使代理,ns.box()也未被引用。 我还尝试将所有对象代理top-&gt; down,也没有成功。

在这样的构造中,甚至可以在事件处理程序中从{{1}}的返回对象访问属性吗?

1 个答案:

答案 0 :(得分:4)

您可以使用范围函数实现此目的,如下所示:

self.addwidget((function() {
    var box = ns.box({                        
                text:       'Foobar',
                fromTop:    ~~(Math.random()*window.innerHeight),
                fromLeft:   ~~(Math.random()*window.innerWidth),
                toTop:      240,
                toLeft:     40,
                css:        'foobar',
                easing:     'easeOutCirc',
                duration:   2000,
                events:     {
                    mousedown:      function(e){
                        e.target.position = {x: e.pageX, y: e.pageY};
                    },
                    mouseup:        function(e){
                        // You can access `box` here                         
                    }
                }
    });

    return {
        box:   box,
        delay: 3000
    };
})());

通过将框分配给我们的作用域函数中的var,我们创建一个符号,使事件处理程序(closures)关闭并因此可以访问。我们立即调用该函数,让它返回对象。闭包所持的参考文献是持久的,所以...

我一直使用这种模式,因为我不喜欢匿名函数(例如,你的事件处理程序是匿名的); more here。如果我正在做上述事情,我会改为命名,如下:

self.addwidget((function() {
    var box = ns.box({                        
                text:       'Foobar',
                fromTop:    ~~(Math.random()*window.innerHeight),
                fromLeft:   ~~(Math.random()*window.innerWidth),
                toTop:      240,
                toLeft:     40,
                css:        'foobar',
                easing:     'easeOutCirc',
                duration:   2000,
                events:     {
                    mousedown:      boxMousedown,
                    mouseup:        boxMouseup
                }
    });

    function boxMousedown(e){
        e.target.position = {x: e.pageX, y: e.pageY};
    }

    function boxMouseup(e){
        // You can access `box` here                         
    }

    return {
        box:   box,
        delay: 3000
    };
})());

这些函数现在具有可以显示在调用堆栈和错误消息中的名称,但它们完全私有,而不会使全局命名空间混乱。