首页 > 解决方案 > 为什么不能在箭头函数中省略getElementById()的参数?

问题描述

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

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

...效果很好。

然后我想,嘿,getElementById正好需要1个参数。没有语法糖吗?所以我写道:

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

......但这没有用。我在 Chrome 上收到“非法调用”。

所以它不是语法糖。这一切的背后是什么?

标签: javascriptecmascript-6

解决方案


JavaScript 在“方法调用”和“函数调用”之间存在区别。前者会设置this,后者不会。从语法上讲,方法调用必须是 form receiver.method(...args)。没有点,没有方法调用。所以这:

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

当你这样做时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");


推荐阅读