代码之家  ›  专栏  ›  技术社区  ›  WSBT

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

  •  2
  • WSBT  · 技术社区  · 7 年前

    假设我有3个 <img> 页面上的标记,我想将它们作为数组获取,因此我写道:

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

    ... 效果很好。

    然后我想,嘿, getElementById 只接受一个参数。不是有语法糖吗?所以我写道:

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

    ... 但那没用。我在Chrome上看到“非法调用”。

    所以这不是语法糖。这些背后是什么?

    2 回复  |  直到 7 年前
        1
  •  6
  •   Amadan    7 年前

    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
    

    当你这样做的时候 map(document.getElementById) , document.getElementById 是从其对象中提取的函数;当 map 调用它,它将在没有接收者的情况下调用它, 不会被安排,事情会变得糟糕。

    有一种方法可以保存它: 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");
        2
  •  3
  •   Mark    7 年前

    如果你能进去 document map() this 参数,它将为调用 getElementById . 但不确定这是否比仅仅使用箭头函数有所改进。

    let myArray = ['img1', 'img2', 'img3'].map(document.getElementById, document)
    
    console.log(myArray)
    <p id="img1"><p>
    <p id="img2"><p>
    <p id="img3"><p>