JavaScript 中的this 非常特殊和强大。它可能意味着任何事情。我在here 和here 中介绍了其中的一些内容,但确实值得找到一个关于JavaScript 的好教程并花一些时间学习它。
我们先看一下jQuery的使用,然后在JavaScript中更一般地谈论它(有点)。
在 jQuery 中,特别是
在使用 jQuery 编写的代码中,this通常指的是作为被调用函数主题的 DOM 元素(例如,在事件回调中)。
示例 jQuery 事件回调(this 包含在 the .bind docs 中):
$("div").click(function() {
// Here, `this` will be the DOM element for the div that was clicked,
// so you could (for instance) set its foreground color:
this.style.color = "red";
// You'll frequently see $(this) used to wrap a jQuery object around the
// element, because jQuery makes lots of things a lot simpler. You might
// hide the element, for example:
$(this).hide();
});
类似地,作用于当前 jQuery 选择器匹配的所有元素的各种 jQuery 函数可以选择接受一个函数,当该函数被调用时,this 再次成为有问题的 DOM 元素——例如,@ 987654324@ 函数允许这样做:
// Find all divs inside the `foo` element, and set
// their content to their CSS class name(s)
// (Okay, so it's a hokey example)
$("#foo div").html(function() {
return this.className;
});
jQuery 使用this 的另一个地方是在jQuery.each 的回调中:
var a = ["one", "two", "three"];
jQuery.each(a, function() {
alert(this);
});
...这将警告“一”,然后是“二”,然后是“三”。如您所见,这是this 的完全不同的用法。
(令人困惑的是,jQuery 有两个函数称为 each,上面的一个在 jQuery/$ 函数本身上并且总是以这种方式调用 [jQuery.each(...) 或 $.each(...)],另一个在 jQuery instances [objects] 而不是 jQuery/$ 函数本身。Here are the docs 对于另一个,我不会在这个答案中讨论另一个,因为它使用 this 的方式与 html 和事件回调,我想展示 jQuery 对this 的不同使用。)
一般在 JavaScript 中
this 指的是一个对象。 更新: 在 ES5 的严格模式中,这不再是真的,this 可以有任何值。在任何给定的函数调用中this 的值由函数的调用方式确定(而不是函数的定义位置,如在 C# 或 Java 等语言中)。调用函数时设置this 的最常见方法是通过对象上的属性调用函数:
var obj = {};
obj.foo = function() {
alert(this.firstName);
};
obj.firstName = "Fred";
obj.foo(); // alerts "Fred"
在那里,因为我们通过obj 上的属性调用了foo,所以在调用期间this 被设置为obj。但不要以为foo 以任何方式与obj 结婚了,这很好用:
var obj = {};
obj.foo = function() {
alert(this.firstName);
};
obj.firstName = "Fred";
obj.foo(); // alerts "Fred"
var differentObj = {};
differentObj.firstName = "Barney";
differentObj.bar = obj.foo; // Not *calling* it, just getting a reference to it
differentObj.bar(); // alerts "Barney"
事实上,foo 与 任何 对象根本没有内在联系:
var f = obj.foo; // Not *calling* it, just getting a reference to it
f(); // Probably alerts "undefined"
在那里,由于我们没有通过对象属性调用f,因此没有明确设置this。当this 没有显式设置时,它默认为全局对象(在浏览器中为window)。 window 可能没有属性 firstName,所以我们在警报中得到“未定义”。
还有其他方法可以调用函数并设置this是什么:通过使用函数的.call和.apply函数:
function foo(arg1, arg2) {
alert(this.firstName);
alert(arg1);
alert(arg2);
}
var obj = {firstName: "Wilma"};
foo.call(obj, 42, 27); // alerts "Wilma", "42", and "27"
call 将 this 设置为您提供的第一个参数,然后将您提供的任何其他参数传递给它正在调用的函数。
apply 做同样的事情,但你将函数的参数作为数组而不是单独提供:
var obj = {firstName: "Wilma"};
var a = [42, 27];
foo.apply(obj, a); // alerts "Wilma", "42", and "27"
// ^-- Note this is one argument, an array of arguments for `foo`
不过,关于 JavaScript 中的this,还有很多需要探索的地方。这个概念很强大,如果你习惯了其他一些语言是如何做到的(而不是如果你习惯了其他一些),那么这个概念会有点欺骗性,并且值得了解。
以下是this 在 ES5 严格模式下不引用对象的一些示例:
(function() {
"use strict"; // Strict mode
test("direct");
test.call(5, "with 5");
test.call(true, "with true");
test.call("hi", "with 'hi'");
function test(msg) {
console.log("[Strict] " + msg + "; typeof this = " + typeof this);
}
})();
输出:
[严格] 直接;这个类型=未定义
[严格] 5;这个类型=数字
【严】以真; typeof this = boolean
[严格] 用'hi'; typeof this = string
而在松散模式下,所有这些都会说typeof this = object; live copy.