Область видимости в объектном литерале - PullRequest
2 голосов
/ 10 сентября 2010

Начну с примера фрагмента:

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 handlers. Конечно, я не могу получить доступ к box.somemethod на этом этапе, потому что я не могу ссылаться на внешнее свойство box на этом этапе. Поэтому я попытался изменить область действия с обработчиков событий с jQuery.proxy() на this, но безуспешно.
this.somemethod не имеет ссылки, даже когда прокси. Я также попытался проксировать все объекты сверху вниз, но безуспешно.

Возможно ли даже в конструкции, подобной этой, получить доступ к свойствам из возвращенного объекта ns.box() в обработчиках событий?

1 Ответ

4 голосов
/ 10 сентября 2010

Этого можно достичь с помощью функции определения объема, например:

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
    };
})());

Назначая поле для переменной внутри нашей функции определения масштаба, мы создаем символ, к которому обработчики событий (которые замыкания ) закрываются и, таким образом, имеют доступ к нему. Мы немедленно вызываем функцию, чтобы она возвращала объект. Ссылки, удерживаемые закрытиями, являются постоянными, и поэтому ...

Я использую этот шаблон все время, потому что мне не нравятся анонимные функции (например, ваши обработчики событий анонимны); больше здесь . Если бы я делал вышеупомянутое, я бы назвал их так:

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
    };
})());

Эти функции теперь имеют имена, которые могут отображаться в стеках вызовов и сообщениях об ошибках, но они полностью закрыты , не загромождая глобальное пространство имен.

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