Анонимная функция теряет область видимости - PullRequest
0 голосов
/ 09 декабря 2011

Почему это не работает?

var img = new Image();
this.dimensions = [ ];
var m = this;
img.onload = function(){ 
    return function(){
        m.dimensions = [ this.width, this.height ]; 
    }
};
img.src = 'images/whatever.jpg';


console.log(this.dimensions);
[]

(внутри объекта JS, отсюда и "this")

РЕДАКТИРОВАТЬ: рабочий код

var img = new Image();
this.dimensions = [  ];
var m = this;
img.onload = function(){ 
    m.dimensions.push(this.width, this.height);  
    console.log(m.dimensions) // had to wait
};
img.src = 'whatever.jpg';

Ответы [ 3 ]

1 голос
/ 09 декабря 2011

Учтите, что этот код не будет предупреждением:

img.onload = function(){ 
    return function(){
        alert("hi")
    }
};

Затем рассмотрите стандартное (вероятно желаемое) «двойное замыкание»:

img.onload = (function(m){ 
    return function(){
        alert(m)
    }
})(this)

Удачного кодирования.

1 голос
/ 09 декабря 2011

Вы уверены, что console.log (this.dimensions) запускается ПОСЛЕ загрузки изображения? То, что вы добавили в img.onload, это функция обратного вызова, которая запускается после завершения загрузки образа в DOM. До завершения загрузки img m.dimensions пока не будут установлены. Изображение не загружается сразу после добавления обратного вызова, но загружается асинхронно и может завершиться в любое время.

Другими словами, вы запускаете console.log (this.dimensions) до того, как измерения будут установлены (до запуска обратного вызова onload). Бьюсь об заклад, если вы поместите console.log в вызов setTimeout, скажем, в течение 5 секунд, он запишет то, что вы ожидали.

1 голос
/ 09 декабря 2011

Это потому, что this меняет значение внутри новых определений функций.Вы решаете это, кэшируя это в локальной переменной.Здесь это уже сделано;Вы сохраняете его в переменной m.Так что просто используйте m вместо this.

var img = new Image();
this.dimensions = [ ];
var m = this;
img.onload = function(){ 
    return function(){
        m.dimensions = [ m.width, m.height ]; 
    }
};
img.src = 'images/whatever.jpg';

Вот хороший урок, объясняющий, как this меняет значение в разных контекстах: http://javascriptweblog.wordpress.com/2010/08/30/understanding-javascripts-this/

...