JavaScript中的this关键字是如何工作的?

4

我一直在进行JavaScript开发,遇到了这个问题。考虑以下代码

var obj = {};
obj.bind = function () {
console.info(this);
};

obj.bind();

我将在FireBug JavaScript控制台上运行代码。预期结果是this会在控制台中显示对对象的引用。
实际上,它显示为undefined
但是,当我对我的代码进行以下更改时:
var obj = {};
obj.bind = function () {
this.x = 'x';
console.info(this);
};

obj.bind();

现在控制台显示了预期的值,即对obj对象的引用,这是为什么呢?涉及到this关键字的使用。

3
我已尝试在Chrome的开发者控制台中执行第一个示例,它按您预期显示了该对象。也许这是Firebug的一个错误? - Jeremy
1
控制台可能会说谎,记住这一点。一个例子是使用delete删除变量。在控制台中有效,在外部无效。 - alex
@Jeremy 不是的。它显示为“未定义”。Chrome 显示对象,但这是因为 Chrome 这样做,而不是 'console.info' 函数造成的。在该对象下方可以找到“未定义”单词。 - Omar Abid
@Omar 你错了。在将 this 写入 obj.bind 中之前,附加一些字符串以确认它。我认为它显示的 undefinedobj.bind() 调用的返回值。 - Jeremy
2个回答

3

undefined是函数的返回值,因为你没有明确返回任何值。

在Chrome和Firebug中,在返回值undefined之前,控制台正确地显示了对象。

所以如果你这样做:

var obj = {};
    obj.bind = function () {
    console.info(this);
    return "foo";
};

obj.bind();

你应该看到类似以下内容:

Object {   }
"foo"

如果 Firebug 在对象为空时没有显示出来,你可能需要检查一下是否使用了最新版本。

-1
在你的例子中,“this”应该是obj,正如一些评论者所指出的那样。以下是说明为什么的详细信息--
在Javascript中,“this”的值取决于您调用函数的方式:
1. 当一个函数被存储为对象的属性,并且您通过调用obj.foo()来调用该函数时,“this”将是obj。
例如:
var obj = {
  x: 1,
  increment: function() {
    this.x = this.x + 1;
};

obj.increment(); // Makes "this" be obj
  1. 当您使用没有引用任何拥有对象的语法调用函数时,“this”将是全局环境。

例如:

function someFunc(a, b) {
     return a + b; // If you were to refer to "this" here, it would be the global env.
}

someFunc(5, 6);
  1. 当您使用new运算符将函数作为构造函数调用时,将为您实例化一个新对象,并且"this"将指向该新对象。

例如:

function SomeConstructor() {
   this.x = 42; // under the hood, a new object was instantiated for you, and "this" was set to it.
}

var result = new SomeConstructor(); // note the "new" keyword

// 结果将是 { x:42 }

  1. 当你使用call()或apply()时,你可以控制"this"是什么。

(这里没有示例,因为它与你的问题相距甚远。查找apply()或call()的文档以获得示例。)


除了在 ES5 严格模式下,如果 this 不能解析为对象,则它将保持不变,而不会像其他情况下一样设置为全局对象(ES5 §10.4.3)。 - RobG
有人能解释一下为什么会被踩吗?我真的不知道哪里出了问题,但如果有问题,我想修复它。 - Charlie Flowers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接