用'this'定义的函数,但没有'this'执行

时间:2012-08-20 18:21:46

标签: javascript

我期待着" taco"函数生成运行时错误,因为我没有使用"这"关键字:

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是否在此使用某种类型的隐式上下文管理?

好奇,谢谢!

3 个答案:

答案 0 :(得分:8)

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

因此,this.taco()实际上是window.taco(),与taco()相同。换句话说,taco()是一个全局函数,因此当taco()为{{window.taco()时,它可以将其称为this.taco()thiswindow。 1}}。

如果您将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调用x = new foo()之类的函数,则会创建foo的新实例,并将this的值设置为该对象在foo()函数内部,默认情况下从foo()返回新实例。

  2. 如果您通常调用foo()之类的任何函数,则this的值将设置为浏览器中window或javascript更新的全局对象“严格”模式,然后this将为undefined。这就是您原始示例中发生的情况。

  3. 如果您使用obj.foo()之类的对象引用调用方法,则this将设置为obj对象。

  4. 如果您使用.apply().call()进行函数调用,那么您可以使用{{1的第一个参数来专门控制this的值设置为什么}或.apply()。例如:.call()会调用foo.call(obj)函数并将foo()指针设置为this对象。

  5. 如果您没有进行任何函数调用(例如,在全局范围内),那么obj将是全局对象(浏览器中为this)或window严格模式。

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

答案 1 :(得分:2)

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

要获得所需的功能,请使用new foo()语法。然后this将引用一个新对象,taco属性将被赋予一个新值(函数)。直接拨打taco会让您收到错误。

答案 2 :(得分: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`