Как правильно ссылаться на исходный объект при изменении области действия

Я полностью начинаю использовать RequireJS, потому что я почувствовал его полезность, но я все еще застрял в простой проблеме программирования: когда у меня заканчивается область видимости (например, когда я кодирую функцию jQuery callback'd), я не знаю точного надлежащий способ ссылаться на то, где я был. У меня есть пример: этот код находится в src/dir моего проекта, у меня есть jquery.js и require.js в lib/.

// src/main.js

define(function() {
 return {
 setup: function(settings){
 this.settings = settings;
 },

 start: function(){
 this.initScr();
 },

 initScr: function(){
 var screen = $('<canvas>').attr({
 width: window.innerWidth,
 height: window.innerHeight
 });
 $('body').append(screen);
 this.DOM.screen = screen[0];
 $(window).resize(function(){
 require(['game/main'], function(game) {
 console.log(this);
 game.DOM.screen.width = window.innerWidth;
 game.DOM.screen.height = window.innerHeight;
 });
 });
 },

 settings: {},
 DOM: {}
 };
});
</canvas>

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

Спасибо за прочтение

Редактировать:

Наконец, я сделал это, чему помог pax162.

define(function() {
 var initScr = function(){
 var screen = $('<canvas>').attr({
 width: window.innerWidth,
 height: window.innerHeight
 });
 $('body').append(screen);
 DOM.screen = screen[0];
 $(window).resize(function(){
 DOM.screen.width = window.innerWidth;
 DOM.screen.height = window.innerHeight;
 });
 };

 var start = function(){
 initScr();
 };

 var setup = function(settings1){
 settings = settings1;
 };

 var settings = {};

 var DOM = {};

 return {
 setup: setup,
 start: start,
 initScr:initScr,
 settings: settings,
 DOM: DOM
 };
});
</canvas>
2 ответа

Вы можете сделать это и сохранить область действия:

define(function() {




var initScr = function(){
 var screen = $('<canvas>').attr({
 width: window.innerWidth,
 height: window.innerHeight
 });
 $('body').append(screen);
 DOM.screen = screen[0];
 $(window).resize(function(){
 require(['game/main'], function(game) {
 //console.log(this);
 game.DOM.screen.width = window.innerWidth;
 game.DOM.screen.height = window.innerHeight;
 });
 });
 };

var start = function(){
 initScr();
 };

var setup = function(settings1){
 settings = settings1;
 };

var settings = {};

var DOM = {};

 return {
 setup: setup,
 start: start,
 initScr:initScr,
 settings: settings,
 DOM: DOM
 };
});
</canvas>


С Javascript 1.8.5 или выше функция Function.prototype.bind - это решение, которое я предпочитаю. В документации указано, что bind:

Создает новую функцию, которая при вызове имеет <code>this</code> ключевое слово, установленное в предоставленное значение, с заданной последовательностью аргументов, предшествующей любому, предоставленному при вызове новой функции.

В вашем случае исходный код можно изменить так, чтобы обработчик изменения размера был установлен следующим образом:

$(window).resize(function(){
 this.DOM.screen.width = window.innerWidth;
 this.DOM.screen.height = window.innerHeight;
}.bind(this));

В то время, когда bind вызов, this имеет значение, которое вы хотите. При изменении размера будет вызываться возвращаемое значение bind, которое является функцией, для которой this связано с тем значением, которое вы хотели бы иметь.

licensed under cc by-sa 3.0 with attribution.