为什么在javascript匿名函数的末尾写".call(this)"?

zod*_*zod 56 javascript

我看过这样写的JavaScript(它是在演示中,我手头没有实际的代码,但暗示这是正常的):

(function() {    

    var a = 1;

    this.sayA = function() {
        alert(a);
    }

}).call(this);

sayA();
Run Code Online (Sandbox Code Playgroud)

我想它是一个匿名函数,因此变量a不是全局可用的.

有什么意义.call(this)呢?由于这个函数没有嵌套,this只是窗口.它与()最后的写作有何不同?

net*_*ica 33

我很好奇这个以及我刚看到John Resig关于这个视频的谈话.Yoshi有一个很好的答案但是我必须在控制台日志中稍微测试才能理解,我认为对他的回答的修改可能会帮助一些像我一样有困难的人:

function Foo() {
  this.foo = true;
  (function () {
      console.log("Foo = " + this.foo);
      // Outputs undefined
  }());
  (function () {
      console.log("Foo = " + this.foo);
      // Outputs true
  }).call(this);

  (function () {
      console.log(this);
      // Outputs undefined in strict mode, or Window in non strict mode
      // Anonymous functions usually default to the global scope
  })();
}

var bar = new Foo;
Run Code Online (Sandbox Code Playgroud)

它让我更有意义地看到第一个和第二个并排,显示.call(this)本质上使你能够将当前上下文传递给匿名函数.

感谢您提出问题并感谢Yoshi的明确答案!


Yos*_*shi 32

试试这个:

function Foo() {

  (function () {
    console.log(this);
    // > Foo
  }).call(this);

  (function () {
    console.log(this);
    // > undefined in strict mode, or Window in non strict mode
  })();
}

var bar = new Foo;
Run Code Online (Sandbox Code Playgroud)

因此,如果出于任何原因使用它,这是使IIFE行为就好像它是成员函数的一种方式Foo,特别是在创建用户定义的对象类型的实例时.

  • 但是与var bar = function(){console.log(this)x 2;}有什么不同? (3认同)

Ber*_*rgi 14

由于这个函数没有嵌套,this只是窗口.它与()最后的写作有何不同?

不 - 不是严格模式:

  1. 如果功能代码是严格代码,请设置ThisBindingthisArg.
  2. 否则,如果thisArgnullundefined,则设置ThisBinding为全局对象.
  3. ...

在严格模式下,this只是直接设置为给定值,这是undefined正常调用.因此,.call(this)用于显式传递全局对象.您可以在控制台中尝试:

> (function() { "use strict"; console.log(this); })()
undefined
> (function() { "use strict"; console.log(this); }).call(this)
Window
Run Code Online (Sandbox Code Playgroud)

它可能对草率代码没有影响,但它是一个很好的做法和未来兼容:-)


Jak*_*cki 13

this传递给函数设置执行的上下文,所以在你的匿名函数里面this引用window.

你可以写this.alert('');.