【TG_duoteJG】多特工作室杰哥duotee.com版权所有,禁止转载
微信飞鸟箭头搭建函数如何处理this
关键字
关于微信飞鸟箭头搭建函数要记住的盘口最重要的事情是它们处理this新圣飞鸟二开
关键字的方式。特别是,this
箭头搭建函数内的盘口关键字不会反弹。
为了说明这意味着什么,请查看下面的演示:
[codepen_embed height=”300″ default_tab=”html,result” slug_hash=”qBqgBmR” user=”SitePoint”]在 CodePen 上的 ( )\
。[/codepen_embed]
这是一个按钮。单击按钮会触发从 5 到 1 的反向计数器,该计数器显示在按钮本身上。
<button class="start-btn">Start Counter</button>...const startBtn = document.querySelector(".start-btn");startBtn.addEventListener('click', function() {
this.classList.add('counting')
let counter = 5;
const timer = setInterval(() => {
this.textContent = counter
counter --
if(counter < 0) {
this.textContent = 'THE END!'
this.classList.remove('counting')
clearInterval(timer)
}
}, 1000) })
注意方法中的事件处理程序.addEventListener()
是一个普通的匿名函数表达式,而不是箭头函数。为什么?如果您this
在函数内部登录,您会看到它引用了已附加侦听器的按钮元素,这正是程序按计划工作所期望的和需要的:
startBtn.addEventListener('click', function() {
console.log(this)
...})
这是 Firefox 开发者工具控制台中的样子:
但是,尝试用箭头函数替换常规函数,如下所示:
startBtn.addEventListener('click', () => {
console.log(this)
...})
现在,this
不再引用该按钮。相反,它引用了Window
对象:
编辑
这意味着,如果您想在this
单击按钮后向按钮添加一个类,例如,您的代码将不起作用:
// change button's border's appearancethis.classList.add('counting')
这是控制台中的错误消息:
编辑
在 JavaScript 中使用箭头函数时,this
关键字的值不会反弹。它继承自父作用域(这称为)。在这种特殊情况下,所讨论的箭头函数作为参数传递给startBtn.addEventListener()
位于全局范围内的方法。因此,this
函数处理程序内部也绑定到全局范围——即Window
对象。
所以,如果要this
在程序中引用开始按钮,正确的做法是使用常规函数,而不是箭头函数。
匿名箭头函数
在上面的演示中,接下来要注意的是.setInterval()
方法中的代码。在这里,您也会找到一个匿名函数,但这次是箭头函数。为什么?
请注意,如果您使用常规函数,值this
会是什么:
const timer = setInterval(function() {
console.log(this)
...}, 1000)
会是button
元素吗?一点也不。这将是Window
对象!
编辑
事实上,上下文已经改变,因为this
现在在一个未绑定或全局函数中,该函数作为参数传递给.setInterval()
. 因此,this
关键字的值也发生了变化,因为它现在绑定到全局范围。
在这种情况下,一个常见的技巧是包含另一个变量来存储this
关键字的值,以便它继续引用预期的元素——在这种情况下,button
元素:
const that = this
const timer = setInterval(function() {
console.log(that)
...}, 1000)
您还可以使用.bind()
来解决问题:
const timer = setInterval(function() {
console.log(this)
...}.bind(this), 1000)
使用箭头函数,问题就完全消失了。这this
是使用箭头函数时的值:
const timer = setInterval( () => {
console.log(this)
...}, 1000)
这一次,控制台记录了我们想要的按钮。其实程序是要改变按钮文字的,所以需要this
引用button
元素:
const timer = setInterval( () => {
console.log(this)
// the button's text displays the timer value
this.textContent = counter}, 1000)
箭头函数没有自己的this
上下文。他们继承了this
父级的价值,正是因为这个特性,他们在上述情况下做出了很好的选择。
JavaScript 箭头函数并不总是适合这项工作的工具
箭头函数不仅仅是一种在 JavaScript 中编写函数的新奇方式。它们有自己的局限性,这意味着在某些情况下您不想使用它们。上一个演示中的点击处理程序就是一个很好的例子,但它不是唯一的。让我们再检查几个。
箭头函数作为对象方法
箭头函数不能很好地作为对象上的方法。这是一个。
考虑这个netflixSeries
对象,它有一些属性和几个方法。调用console.log(netflixSeries.getLikes())
应该打印一条带有当前点赞数的消息,调用console.log(netflixSeries.addLike())
应该将点赞数加一,然后在控制台上打印带有感谢消息的新值:
const netflixSeries = {
title: 'After Life',
firstRealease: 2019,
likes: 5,
getLikes: () => `${this.title} has ${this.likes} likes`,
addLike: () => {
this.likes++
return `Thank you for liking ${this.title}, which now has ${this.likes} likes`
} }
相反,调用该.getLikes()
方法返回“undefined has NaN likes”,调用该.addLike()
方法返回“Thank you for like like undefined, which now has NaN likes”。所以,this.title
并this.likes
不能分别引用对象的属性title
和likes
。
再一次,问题在于箭头函数的。对象的this
内部方法是引用父级的作用域,在这种情况下是Window
对象,而不是父级本身——也就是说,不是netflixSeries
对象。
当然,解决方案是使用常规函数:
const netflixSeries = {
title: 'After Life',
firstRealease: 2019,
likes: 5,
getLikes() {
return `${this.title} has ${this.likes} likes`
},
addLike() {
this.likes++
return `Thank you for liking ${this.title}, which now has ${this.likes} likes`
} }// call the methods console.log(netflixSeries.getLikes())console.log(netflixSeries.addLike())// output: After Life has 5 likes
Thank you for liking After Life, which now has 6 likes
第三方库的箭头函数
另一个需要注意的问题是第三方库通常会绑定方法调用,以便this
值指向有用的东西。
例如,在 jQuery 事件处理程序中,this
您可以访问处理程序绑定到的 DOM 元素:
$('body').on('click', function() {
console.log(this)})//
但是如果我们使用箭头函数——正如我们所见,它没有自己的this
上下文——我们会得到意想不到的结果:
$('body').on('click', () =>{
console.log(this)})// Window
这是使用的另一个示例:
new Vue({
el: app,
data: {
message: 'Hello, World!'
},
created: function() {
console.log(this.message);
}})// Hello, World!
在created
钩子内部,this
绑定到 Vue 实例,所以“Hello, World!” 显示信息。
但是,如果我们使用箭头函数,this
它将指向没有message
属性的父作用域:
new Vue({
el: app,
data: {
message: 'Hello, World!'
},
created: function() {
console.log(this.message);
}})// undefined
箭头函数没有arguments
对象
有时,您可能需要创建一个参数数量不定的函数。例如,假设您要创建一个函数,按偏好排序列出您最喜欢的 Netflix 连续剧。但是,您还不知道要包含多少个系列。JavaScript 使arguments对象可用。这是一个类似数组的对象(不是完整的数组),它存储调用时传递给函数的值。
尝试使用箭头函数
const listYourFavNetflixSeries = () => {
// we need to turn the arguments into a real array
// so we can use .map()
const favSeries = Array.from(arguments)
return favSeries.map( (series, i) => {
return `${series} is my #${i +1} favorite Netflix series`
} )
console.log(arguments)}console.log(listYourFavNetflixSeries('Bridgerton', 'Ozark', 'After Life'))
当您调用该函数时,您将收到以下错误消息:Uncaught ReferenceError: arguments is not defined
. 这意味着该arguments
对象在箭头函数中不可用。事实上,用常规函数替换箭头函数就可以了:
const listYourFavNetflixSeries = function() {
const favSeries = Array.from(arguments)
return favSeries.map( (series, i) => {
return `${series} is my #${i +1} favorite Netflix series`
} )
console.log(arguments)
}console.log(listYourFavNetflixSeries('Bridgerton', 'Ozark', 'After Life'))// output: ["Bridgerton is my #1 favorite Netflix series", "Ozark is my #2 favorite Netflix series", "After Life is my #3 favorite Netflix series"]
因此,如果您需要该arguments
对象,则不能使用箭头功能。
但是,如果您真的想使用箭头函数来复制相同的功能怎么办?您可以做的一件事是使用ES6 剩余参数( ...
)。以下是重写函数的方法:
const listYourFavNetflixSeries = (...seriesList) => {
return seriesList.map( (series, i) => {
return `${series} is my #${i +1} favorite Netflix series`
} )
}
结论
通过使用箭头函数,您可以编写带有隐式返回的简洁单行语句,并且最终忘记旧时的技巧来解决this
JavaScript 中关键字的绑定问题。箭头函数也适用于数组方法,如.map()
, .sort()
, .forEach()
,.filter()
和.reduce()
。但请记住:箭头函数不会取代常规的 JavaScript 函数。请记住,仅当它们是适合工作的工具时才使用 JavaScript 箭头函数。
\