将箭头函数转换为常规函数?

1 javascript ecmascript-6

我正在阅读 Wes Bos 的《Javascript 30》。

我正在做 AJAX 类型预习课程,并且我有点试图限制我在上面做的 ES6 的数量,只是为了练习。

这是完成的版本:

https://codepen.io/Airster/pen/KNYXYN

请注意,当您输入位置时,搜索到的值会在结果中以黄色突出显示。

现在确定这一点的 JavaScript 是 displayMatches 函数:

var displayMatches = function(){
    console.log(this.value);
    var matchArray = findMatches(this.value, cities);
    var html = matchArray.map(function(place){
        console.log(this, place, "test");
        var regex = new RegExp(this.value, 'gi');
        var cityName = place.city.replace(regex, "<span class='hl'>" + this.value + "</span>");
        var stateName = place.state.replace(regex, "<span class='hl'>" + this.value + "</span>");
            return `
          <li>
            <span class="name">${cityName}, ${stateName}</span>
            <span class="population">${place.population}</span>
          </li>
            `;
    }).join("");
    suggestions.innerHTML = html;
}
Run Code Online (Sandbox Code Playgroud)

问题在于函数变量html。目前我把它作为:

var html = matchArray.map(function(place){...})

这不起作用,我的结果将是不确定的。

但是,如果我将其更改为箭头函数:

var html = matchArray.map(place => {...})

该函数将运行并且搜索到的值将突出显示。

有人可以解释为什么在这个特定的上下文中,箭头函数起作用吗?

提前致谢!

jfr*_*d00 5

有人可以解释为什么在这个特定的上下文中,箭头函数起作用吗?

箭头函数(根据定义)保留 的当前词法值this。常规回调函数则不然。this因此,当您使用常规回调函数时,您会丢失代码所依赖的正确值。

您可以通过使用保留当前范围值的箭头函数this或将可选参数传递thisArg.map()函数之后作为参数来解决此问题。

MDN 文档Array.prototype.map,您可以看到可选的thisArg

var new_array = arr.map(function callback(currentValue, index, array) {
    // Return element for new_array
}[, thisArg])
Run Code Online (Sandbox Code Playgroud)

因此,为了使您的代码this在没有箭头函数的情况下保留,您可以将 传递thisArg给您调用的.map().

var displayMatches = function(){
    console.log(this.value);
    var matchArray = findMatches(this.value, cities);
    var html = matchArray.map(function(place){
        console.log(this, place, "test");
        var regex = new RegExp(this.value, 'gi');
        var cityName = place.city.replace(regex, "<span class='hl'>" + this.value + "</span>");
        var stateName = place.state.replace(regex, "<span class='hl'>" + this.value + "</span>");
            return `
          <li>
            <span class="name">${cityName}, ${stateName}</span>
            <span class="population">${place.population}</span>
          </li>
            `;
    }, this).join("");              // <== See the this argument passed here
    suggestions.innerHTML = html;
}
Run Code Online (Sandbox Code Playgroud)

仅供参考,为了完整起见,这里实际上有六种可能的解决方案:

  1. this参数传递给.map()如上所示
  2. 使用箭头函数(仅限 ES6)
  3. .bind(this)与回调函数一起使用
  4. 创建局部变量var self = this;和引用self而不是this.
  5. let val = this.value在回调之前使用,然后val在回调内部使用(代码如下所示)。
  6. e参数声明给事件处理程序并使用e.target.value而不是,根本this.value不需要使用。this

由于.map()具有所需的内置功能this,如果您不打算使用 ES6 箭头函数,那么对我来说使用参数最有意义.map(),但这四种解决方案都可以工作。


查看this回调中正在执行的操作的详细信息,您只是在阅读this.value,因此您也可以let val = this.val在回调之前抓取并在回调内部使用- 甚至根本val不需要使用。this

var displayMatches = function(){
    let val = this.value;
    console.log(val);
    var matchArray = findMatches(val, cities);
    var html = matchArray.map(function(place){
        console.log(this, place, "test");
        var regex = new RegExp(val, 'gi');
        var cityName = place.city.replace(regex, "<span class='hl'>" + val + "</span>");
        var stateName = place.state.replace(regex, "<span class='hl'>" + val + "</span>");
            return `
          <li>
            <span class="name">${cityName}, ${stateName}</span>
            <span class="population">${place.population}</span>
          </li>
            `;
    }).join("");
    suggestions.innerHTML = html;
}
Run Code Online (Sandbox Code Playgroud)