为什么我不能在箭头函数中省略getElementById()的参数?

use*_*613 2 javascript ecmascript-6

假设我<img>在页面上有3个标签,我想将这些作为一个数组,所以我写道:

let myArray = ['img1', 'img2', 'img3'].map(id => document.getElementById(id));

......运作良好.

然后我想,嘿,getElementById只拿了一个参数.是不是有语法糖?所以我写道:

let myArray = ['img1', 'img2', 'img3'].map(document.getElementById);

......但那没用.我在Chrome上收到了"非法调用".

所以它不是语法糖.这些背后的原因是什么?

Ama*_*dan 6

JavaScript在"方法调用"和"函数调用"之间有区别.前者将设定this,后者则不会.从语法上讲,方法调用必须是形式的receiver.method(...args).没有点,没有方法调用.所以这:

document.getElementById(id) // method call, `this` is set to `document`
m = document.getElementById; m(id) // function call, `this` is not set
Run Code Online (Sandbox Code Playgroud)

当你这样做时map(document.getElementById),document.getElementById是一个从它的对象中拔出的函数; 当map调用它时,它将在没有接收器的情况下调用它,this不会被设置,并且事情变得糟糕.

有一种方法可以保存它:bind通过将接收器绑定到它来"方法化"一个函数:map(document.getElementById.bind(document))应该有效.

编辑:进一步说明:

let foo = {
  bar: function(context) {
    let receiver =
      (this == window) ? "window" :
      (this == foo) ? "foo" :
      "unknown";
    console.log(context + ", `this` is `" + receiver + "`");
  }
}

function call(fn, param) {
  fn(param);
}

foo.bar("In direct call");
let baz = foo.bar; baz("When assigned to a variable");
call(foo.bar, "When passed as a parameter")
let quux = foo.bar.bind(foo); quux("When bound to foo");
Run Code Online (Sandbox Code Playgroud)