4

我期待“taco”函数的第二次调用会生成运行时错误,因为我没有使用“this”关键字调用它:

function foo() {
    var bar = "baz";

    this.taco = function() {
        console.log(bar);
    };
    this.taco();
    taco(); // I expected a runtime error here.     
}

foo();

但是,事实并非如此。

这是相同代码的小提琴:http: //jsfiddle.net/phillipkregg/gdFxU/226/

JavaScript 是否在这里使用某种类型的隐式上下文管理?

只是好奇,谢谢!

4

3 回答 3

8

原因是当您调用 时foo(),您是在window对象范围内调用它。这意味着在 的内部foo(), 的值this设置为window

因此,this.taco()is 实际上window.taco()与 相同taco()。换句话说,taco()是一个全局函数,因此无论您将其称为 as taco()、 aswindow.taco()还是 as this.taco()when thisis ,它都可以工作window

如果您taco()像这样涉及一个新对象,其中this设置为的新实例foo并且不等于window,那么您会得到预期的运行时错误:

function foo() {
    var bar = "baz";

    this.taco = function() {
        console.log(this);
        console.log(bar);
    };
    this.taco();
    taco(); // I expected a runtime error here.     
}

var x = new foo();

示例:http: //jsfiddle.net/jfriend00/3LkxU/


如果您对 的值感到困惑this,可以使用以下 javascript 规则来确定 的值this

  1. new如果您使用like调用函数x = new foo(),则会创建一个新实例,foo并将值this设置为函数内部的该对象,并且默认情况foo()下会返回该新实例。foo()

  2. 如果您通常调用任何foo()函数如 这就是您原始示例中发生的情况。thiswindowthisundefined

  3. 如果您调用具有对象引用的方法obj.foo()this则将被设置为obj对象。

  4. 如果您使用.apply()or进行函数调用.call(),那么您可以专门控制使用orthis的第一个参数设置的值。例如:将调用函数并设置指向对象的指针。.apply().call()foo.call(obj)foo()thisobj

  5. 如果您不在任何函数调用中(例如在全局范围内),那么this将是全局对象(window在浏览器中)或undefined处于严格模式。

  6. 与上述所有规则一样,this由调用者调用您的方式控制,而不是函数/方法的定义方式。

于 2012-08-20T18:27:52.263 回答
2

原因是this在 foo() 中,当它按原样调用时,将引用一个全局对象。这意味着taco函数将在全局范围内引入。

要获得您想要的功能,请改用new foo()语法。然后this将引用一个新对象,该taco属性将被赋予一个新值(函数)。直接打电话taco会给你一个错误。

于 2012-08-20T18:26:17.177 回答
1
foo(); // equals window.foo() , `this` equals `window` and `this.taco` equals `window.taco` and `window.taco`  equals `taco` as it is global

new foo(); //creates a new object. this will give error because here `this.taco` is not `taco`
于 2012-08-20T18:30:42.310 回答