JavaScript 范围,为什么 $(this) 等于 [window]?



我有一个ajax函数(不确定是否相关)可以更新html并创建一些链接:

<a href="#" class="clickme" onclick="column_click()" title="my title">click me</a>

我不确定为什么,但是点击,如果我提醒$(this).attr('title')它显示为undefined,如果我提醒$(this)它会显示[window]

function column_click(){
value = $(this);
console.log(value);
thetitle= $(this).attr('title');
console.log(thetitle);
}

有谁知道为什么会这样?

这应该可以解决问题。

onclick="column_click.call(this);"

原因是您的"点击处理程序"实际上只是一个函数。默认设置是让this引用window对象。

在我上面的例子中,我们说"执行column_click并确保this引用a元素。

你混淆了JS/jQuery事件处理的突兀和不显眼的样式。在不显眼的样式中,您可以在 JavaScript 本身中设置点击处理程序,而不是在onclick属性中设置:

$('.clickme').on('click', column_click);

在处理事件时,上述内容会自动将this绑定到单击的元素。

但是,这不是标准的JavaScript!这是jQuery的一个特性。on方法足够智能,可以在函数处理事件时将函数绑定到 HTML 元素。onclick="column_click"不这样做,因为它不是jQuery。它使用标准的 JS 行为,即默认将this绑定到全局对象window

顺便说一下,你看到[window]的原因是$(this)window包装在一个jQuery对象中,所以它看起来像一个数组,里面有window对象。

有三种主要方法可以处理您的问题:

  1. 使用不显眼的绑定:$('.clickme').on('click', column_click);在页面末尾的脚本中或$(document).ready处理程序中的某个位置
  2. 手动绑定thisonclick="column_click.call(this)"
  3. 完全避免使用this

    function column_click(e) {
    var value = $(e.target);
    //...
    

其中,为了良好的编码,我强烈建议使用 1 或 3。

需要在函数中传递参数column_click

<a href="#" class="clickme" onclick="column_click(this)" title="my title">click me</a>

function column_click(obj){
value = $(obj);
console.log(value);
}

注意:this引用window对象。 所以不会按照您的期望工作。

this

简要概述*

在 JavaScript 中执行函数时,默认thiswindow

function foo() {
console.log(this);
}
foo(); // => window

可以通过多种方式更改this值。一种方法是将函数作为对象的方法调用:

var x = {
foo: function() {
console.log(this);
}
};
x.foo(); // => This time it's the x object.

另一种方法是使用callapply告诉函数在特定对象的上下文中执行。

function foo() {
console.log(this);
}
foo.call(x); // => x object again
foo.apply(x); // => x object as well

如果在nullundefinedcallapply,默认行为将再次发生:该函数将在window的上下文中执行:

function foo() {
console.log(this);
}
foo.call(null); // => window
foo.apply(undefined); // => window

但是,请注意,在 ECMAScript 5严格模式下this并不默认为 window:

(function() {
'use strict';
function foo() {
console.log(this);
}
foo(); // => undefined
foo.call(null); // => null
foo.apply(undefined); // => undefined
})();

还可以通过在调用对象之前使用bind将函数绑定到对象来设置this

function foo() {
console.log(this);
}
var bar = {
baz: 'some property'
};
var foobar = foo.bind(bar);
foobar(); // => calls foo with bar as this

结论

您正在使用以下代码:

<a href="#" class="clickme" onclick="column_click()" title="my title">click me</a>

这意味着当单击链接时,它会执行column_click();.这意味着column_click函数作为普通函数而不是方法执行,因为(1)它不是作为对象的属性(someobject.column_click();)调用的,(2)它不是用callapply调用的,(3)它不是用bind调用的。由于它不在严格模式下运行,因此默认thiswindow

如何解决您的问题

因此,要解决您的问题,您可以简单地使用call(或apply)来告诉函数在元素的上下文中执行。在属性值内的小代码中,this引用元素。所以我们可以使用column_click.call(this).就是这么简单!

<a href="#" class="clickme" onclick="column_click.call(this);" title="my title">click me</a>

但是,仅将元素作为参数传递可能更有意义:

<a href="#" class="clickme" onclick="column_click(this);" title="my title">click me</a>

并更改函数以接受参数:

function column_click(el) {
// Use el instead of this...
}

*获取技术

JavaScript 中的this动态范围的。此行为不同于词法作用域的所有其他变量。其他变量没有不同的绑定,具体取决于函数的调用方式;它们的范围来自它们在脚本中出现的位置。 但是,this的行为不同,并且可以具有不同的绑定,而不是取决于它在脚本中的显示位置,而是取决于它的调用方式。对于学习该语言的人来说,这可能是一个混乱的根源,但为了成为一名熟练的JavaScript开发人员,掌握它是必要的。

你正在使用jQuery对吗? 为什么不呢:

$(".clickme").click(function() {
value = $(this);
console.log(value);
thetitle= $(this).attr('title');
console.log(thetitle);
});
// or
$(".clickme").click(column_click);

最新更新