2013-08-20 119 views
2
<section id="clickme"> 
    <p>Stuff goes here.</p> 
</section> 


$("#clickme").on("click", function(){ 
    alert(this.innerHTML); 
    setTimeout(function(){ 
       alert(this.innerHTML); 
    }, 1000); 
}) 

有谁知道为什么第二个警报是未定义的?这个为什么说undefined?

回答

0

上下文在内部函数内发生变化。如果你想使用其中的目标,则需要事先将其设置等于this一个变种,如:

$("#clickme").on("click", function(){ 
    alert(this.innerHTML); 
    var that = this; 
    setTimeout(function(){ 
       alert(that.innerHTML); 
    }, 1000); 
}) 

Fiddle

+0

但为什么它给了我一个未定义的结果? –

+0

@PenghanYang:因为在'setTimeout'处理程序中,'this'是'window'(因为'setTimeout'实际上是'window.setTimeout');所以'this.innerHTML'是'window.innerHTML',这不是你想要的。 – Amadan

+0

@彭汉阳,这里有很多关于javascript上下文的参考资料[了解Javascript上下文](http://joshuakehn.com/2011/10/20 /Understanding-JavaScript-Context.html)和[Javascript this different contexts](http://www.impr essivewebs。com/javascript-this-different-contexts /) – smerny

2

this变化。使用bind(有效地做同样的事情)

var that = this; 
setTimeout(function(){ 
      alert(that.innerHTML); 
}, 1000); 

或:你可以简单地进行代理this(保存到其他地方),避免它。

0

setTimeout()是Window对象的一种方法。 'this'指向没有innerHTML的Window。

+0

非常感谢!你可以再解释一下吗?我是一个noob ... –

+0

你的“setTimeout(function(){...”实际上是“window.setTimeout(function(){...”)的缩写,并且该函数被注册为一个事件当事件被触发时,它与你的“#clickme”对象没有任何关系,但它是实际执行函数中代码的窗口对象,所以'this'必须指向窗口对象 – jaeheung

2

至于什么@jaeheung回答:

setTimeout()是Window对象的一种方法。 'this'指向没有innerHTML的Window。

只是创建一个变量来存储对象,所以没有冲突。

$("#clickme").on("click", function(){ 
    var myObj = this; 
    alert(myObj.innerHTML); 
    setTimeout(function(){ 
       alert(myObj.innerHTML); 
    }, 1000); 
}) 
0

您的代码就相当于:

$("#clickme").on("click", function(){ 
    alert(this.innerHTML);    // `this` points to the event object (`section`) 
    window.setTimeout(function(){  // notice the 'window.' 
       alert(this.innerHTML); // `this` now points to `window` 
    }, 1000); 
}) 

undefined错误来,因为this.innerHTML转化为window.innerHTML因为内部thiswindowwindow对象没有innerHTML属性,因此它会导致undefined属性。

为了使用section元素对象,你需要它缓存在一个变量的地方:

$("#clickme").on("click", function(){ 
    var _this = this;     // cached 
    alert(_this.innerHTML);   // use cached 
    setTimeout(function(){ 
     alert(_this.innerHTML);   // use cached 
    }, 1000); 
}) 

或者,我不知道会在IE是工作的方法把它作为一个参数为setTimeout

$("#clickme").on("click", function(){ 
    alert(this.innerHTML);    // `this` points to the event object (`section`) 
    setTimeout(function(_this){   // notice the `_this` as a parameter 
       alert(_this.innerHTML); // `_this` now points to the argument 
    }, 1000, this);      // pass it here 
})