在jquery中,this
代表什么,以及它在何时使用?
在jquery中,this
代表什么,以及它在何时使用?
this
在JavaScript中非常特殊和强大。它可以意味着几乎任何东西。我在这里和这里涵盖了一些内容,但真的值得找一个好的JavaScript教程并花点时间学习。
让我们先看看jQuery的使用,然后再更普遍地讨论JavaScript(稍微)。
在使用jQuery编写的代码中,this
通常指调用函数的DOM元素(例如,在事件回调中)。
示例jQuery事件回调(关于this
是什么在.bind
文档中有介绍):
$("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元素,例如,html
函数允许这样做:
// 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.each
的回调函数中,jQuery还会使用this
:
var a = ["one", "two", "three"];
jQuery.each(a, function() {
alert(this);
});
...这将会触发 "one",然后是 "two",最后是 "three"。正如你所看到的,这是一种完全不同的使用方式 this
。
(令人困惑的是,jQuery 有两个名为 each
的函数,上面那个是在 jQuery/$ 函数本身上的,并且总是以这种方式调用 [jQuery.each(...)
或 $.each(...)
],而不是在 jQuery 实例 [对象] 上的另一个不同的函数。这里是其他函数的文档,我在这个答案中不讨论其他函数,因为它与 html
和事件回调使用相同的 this
,而我想展示 jQuery 对 this
的一个不同的用法。)
更新:自 ES5 的严格模式起,这就不再正确了,this
指的是一个对象。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
属性,因此我们在警报中得到了"undefined"。
还有其他调用函数和设置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
与call
相同,但你需要将函数的参数以数组的形式传递。
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
还有很多需要探索的内容。这个概念非常强大,如果你习惯了其他一些语言的方式,可能会有点误导(但对于其他一些语言则不是)。了解这个概念非常值得。
下面是一些在ES5严格模式下this
不指向对象的例子:
(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);
}
})();
输出:
[Strict] 直接; typeof this = undefined [Strict] with 5; typeof this = number [Strict] with true; typeof this = boolean [Strict] with 'hi'; typeof this = string
而在松散模式下,所有这些都会说typeof this = object
; live copy。
this
的值设置为任意值 - 在严格模式下,它甚至可能不是一个对象引用,而是一个原始值。 - T.J. Crowderthis关键字
在JavaScript中,称为this的东西是“拥有”JavaScript代码的对象。
当在函数中使用时,this的值是“拥有”该函数的对象。当在对象中使用时,this的值是对象本身。 在对象构造函数中,this关键字没有值。它只是新对象的替代品。当使用构造函数创建一个对象时,this的值将变成新对象。
请注意,this不是一个变量。它是一个关键字。您无法改变this的值。
以下是我简单的解释:
this
指的是调用 function
的 object
。
因此,看这个例子:
var foo = {
name: "foo",
log: function(){
console.log(this.name);
}
}
var bar = {
name: "bar"
}
bar.log = foo.log;
bar.log();
bar对象将foo的log方法引用存储到自己的log属性中,供自己使用。现在当bar调用其log方法时,this将指向bar,因为该方法是由bar对象调用的。
这适用于任何其他对象,甚至是window对象。如果通过全局作用域调用函数,则this将指向window对象。
通过使用函数的bind或call方法,可以显式地定义执行期间对象this
将引用哪个对象。
有趣的事实:在全局作用域
(即顶层/级别)中定义的任何内容都成为window对象
的属性(全局作用域= window对象)。
“javascript this” 的谷歌搜索结果前一位:http://www.quirksmode.org/js/this.html
编辑:我认为关键句子是:
“在 JavaScript 中,“this” 总是指正在执行的函数的“所有者”,或者更确切地说,是该函数作为方法的对象。”
Quirksmode(通常*)非常出色,值得详细阅读整篇文章。
*显然,这种说法不一定正确,请参见 T.J. Crowder 的下面评论。
常规函数属于定义这些函数的类,调用函数的同一对象作为第一个参数传递给函数,并使用this
关键字处理它;
当从类创建对象时,它仅包含一组属性,而对象中没有函数。函数属于类。 但是,如何通过对象调用函数呢?
请考虑以下代码。
var obj = {
p1: 'property 1',
func1 () {
return this.p1
},
func2 (param) {
return this.p1 + param
}
}
同时也可以通过obj
对象调用函数
obj.func1 ();
obj.func2 ('A');
var obj = {
p1: 'property 1',
func1 (this) {
return this.p1
},
func2 (this, param) {
return this.p1 + param
}
}
func1 (obj);
func2 (obj, 'A');
使用 bind
方法可以创建一个新函数,该函数不属于类,并可以将 'this' 参数设置为固定对象;
this.func1 = this.func1.bind(aObject)
this
绑定到定义箭头函数的对象,并将该对象作为 this
参数传递给函数。