调用函数bar
时“this”的行为令我感到困惑。请参阅下面的代码。当从单击处理程序调用bar而不是html元素时,有没有办法安排“this”成为一个普通的旧js对象实例?
// a class with a method
function foo() {
this.bar(); // when called here, "this" is the foo instance
var barf = this.bar;
barf(); // when called here, "this" is the global object
// when called from a click, "this" is the html element
$("#thing").after($("<div>click me</div>").click(barf));
}
foo.prototype.bar = function() {
alert(this);
}
答案 0 :(得分:35)
欢迎来到javascript世界! :d
你已经徘徊在javascript范围和闭包领域。
简短回答:
this.bar()
在 foo 的范围内执行,(因为此指的是 foo )
var barf = this.bar;
barf();
在全球范围内执行。
this.bar基本上意味着:
执行this.bar指向的函数,在 this (foo)的范围内。 将this.bar复制到barf时,运行barf。 Javascript理解为,运行barf指向的函数,并且由于没有 this ,它只在全局范围内运行。
要更正此问题,您可以更改
barf();
这样的事情:
barf.apply(this);
这会告诉Javascript在执行它之前将 this 的范围绑定到barf。
对于jquery事件,您需要使用匿名函数,或者在原型中扩展bind函数以支持范围。
欲了解更多信息:
答案 1 :(得分:5)
QuirksMode提供的JavaScript this
关键字有很好的解释。
答案 2 :(得分:3)
你可能会发现:
Controlling the value of 'this' in a jQuery event
或者这个:
http://www.learningjquery.com/2007/08/what-is-this
有用的。
答案 3 :(得分:2)
您可以在函数上使用Function.apply
来设置this
应该引用的内容:
$("#thing").after($("<div>click me</div>").click(function() {
barf.apply(document); // now this refers to the document
});
答案 4 :(得分:2)
获取书籍:JavaScript:好的部分。
此外,道格拉斯克罗克福德尽可能多地阅读 http://www.crockford.com/javascript/
答案 5 :(得分:1)
这是因为此始终是函数附加到的实例。在EventHandler的情况下,它是触发事件的类。
你可以用这样的匿名函数来帮助你自己:
function foo() {
var obj = this;
$("#thing").after($("<div>click me</div>").click(function(){obj.bar();}));
}
foo.prototype.bar = function() {
alert(this);
}
答案 6 :(得分:0)
this.bar(); // when called here, "this" is the foo instance
当foo用作普通函数而不是构造函数时,此注释是错误的。 这里:
foo();//this stands for window