我正在阅读 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 => {...})
该函数将运行并且搜索到的值将突出显示。
有人可以解释为什么在这个特定的上下文中,箭头函数起作用吗?
提前致谢!
有人可以解释为什么在这个特定的上下文中,箭头函数起作用吗?
箭头函数(根据定义)保留 的当前词法值this。常规回调函数则不然。this因此,当您使用常规回调函数时,您会丢失代码所依赖的正确值。
您可以通过使用保留当前范围值的箭头函数this或将可选参数传递thisArg给.map()函数之后作为参数来解决此问题。
从MDN 文档中Array.prototype.map,您可以看到可选的thisArg:
Run Code Online (Sandbox Code Playgroud)var new_array = arr.map(function callback(currentValue, index, array) { // Return element for new_array }[, thisArg])
因此,为了使您的代码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)
仅供参考,为了完整起见,这里实际上有六种可能的解决方案:
this参数传递给.map()如上所示.bind(this)与回调函数一起使用var self = this;和引用self而不是this.let val = this.value在回调之前使用,然后val在回调内部使用(代码如下所示)。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)