匿名函数丢失范围

时间:2011-12-09 05:46:16

标签: javascript scope anonymous-function

为什么这不起作用?

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 个答案:

答案 0 :(得分:1)

那是因为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/

答案 1 :(得分:1)

请考虑此代码不会提醒:

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

然后考虑标准(可能需要)“双重封闭”:

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

快乐的编码。

答案 2 :(得分:1)

你确定在图像加载后运行console.log(this.dimensions)吗?您添加到img.onload的是在图像加载完DOM后运行的回调函数。在img完成加载之前,m.dimensions尚未设置。添加回调时图像不会立即加载,而是异步加载并且可以在任何时候完成。

换句话说,在设置维度之前(运行onload回调之前),您正在运行console.log(this.dimensions)。我敢打赌,如果你将console.log包装在一个setTimeout调用中,比如5秒,那么它会记录你的预期。

相关问题