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

时间:2012-11-14 05:10:08

标签: javascript scope

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

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

我不知道为什么,但是onclick,如果我提醒$(this).attr('title')它显示为undefined,如果我提醒$(this)它显示[window]

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

            thetitle= $(this).attr('title');
            console.log(thetitle);
        }

有谁知道为什么会这样?

5 个答案:

答案 0 :(得分:3)

这应解决问题。

onclick="column_click.call(this);"

原因是你的“点击处理程序”实际上只是一个功能。默认设置是this引用window对象。

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

答案 1 :(得分:2)

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

如果您callapplynullundefined,则会再次出现默认行为:该函数将在window的上下文中执行:

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

但请注意,在ECMAScript 5 严格模式中,this不会默认为窗口:

(function() {

    'use strict';

    function foo() {
        console.log(this);
    }

    foo(); // => undefined
    foo.call(null); // => null
    foo.apply(undefined); // => undefined

})();

您还可以使用this设置bind,以便在调用对象之前将其绑定到对象:

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)它不是用{{ 1}}或call,以及(3)不会使用apply调用它。由于它未在严格模式下运行,因此默认bindthis

如何解决问题

因此,为了解决您的问题,您只需使用window(或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>

* 获取技术

JavaScript中的

function column_click(el) { // Use el instead of this... } 动态范围。此行为与词法范围的所有其他变量不同。其他变量没有不同的绑定,具体取决于调用函数的 ;它们的范围来自,其中它们出现在脚本中。 this但行为有所不同,并且可以有不同的绑定,这取决于它出现在脚本中的 where ,而不是 它的调用方式。对于学习语言的人来说,这可能会引起混淆,但掌握它是必要的,以便成为一名熟练的JavaScript开发人员。

答案 2 :(得分:2)

您需要在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对象。所以不会按照你的期望工作。

答案 3 :(得分:2)

你混淆了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);处理程序
  2. 中的某个位置使用不显眼的绑定:$(document).ready
  3. 手动绑定thisonclick="column_click.call(this)"
  4. 完全避免使用this

    function column_click(e) {
        var value = $(e.target);
        //...
    
  5. 其中,为了良好的编码,我强烈建议使用1或3。

答案 4 :(得分:0)

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

$(".clickme").click(function() {
  value = $(this);
  console.log(value);

  thetitle= $(this).attr('title');
  console.log(thetitle);
});

// or

$(".clickme").click(column_click);