为了保证的可读性, 本文采用意译而非直译.
这些年来, ES6 将 JS 的可用性提升到一个新的水平时: 箭头函数, 类等等, 这些都很棒.
箭头函数是最有价值的新功能之一, 有很多好文章描述了它的上下文透明性和简短的语法.
但每个事务都有两面. 通常, 新特性会带来一些混乱, 其中之一就是箭头函数被误导了. 本文将介绍一些场景, 在这些场景中, 你应该绕过箭头函数, 转而使用良好的旧函数表达式或较新的简写语法. 并且要注意缩短代码, 因为这会影响代码的可读性.
我自己是一名从事了多年开发的 web 前端老程序员, 目前辞职在做自己的 Web 前端私人定制课程, 今年年初我花了一个月整理了一份最适合 2019 年学习的 Web 前端学习干货, 各种框架都有整理, 送给每一位前端小伙伴, 想要获取的可以添加我的 Web 前端交流群 600610151, 即可免费获取.
1. 定义对象上的方法
在 JavaScript 中, 方法是存储在对象属性中的函数. 当调用该方法时, this 将指向该方法所属的对象.
Object literal
由于箭头函数有一个语法简短, 所以使用它来定义方法是很有吸引力的, 让我们试一试:
calculate.sum 方法用箭头函数定义. 但是在调用时, calculate.sum() 会抛出一个 TypeError, 因为 this.array 为 undefined.
当调用 calculate 对象上的方法 sum() 时, 上下文仍然是 Windows. 之所以会发生这种情况, 是因为箭头函数按词法作用域将上下文绑定到 Windows 对象.
执行 this.array 等同于 Windows.array, 它是 undefined.
解决方法是使用通常函数表达式来定义方法. this 是在调用时确定的, 而不是由封闭的上下文决定的, 来看看修复后的版本:
因为 sum 是常规函数, 所以在调用 calculate.sum() 时 this 是 calculate 对象. this.array 是数组引用, 因此正确计算元素之和: 6.
Object prototype
同样的规则也适用于在原型对象上定义方法. 使用一个箭头函数来定义 sayCatName 方法, this 指向 Windows
使用早期的方式定义函数表达式:
sayCatName 常规函数在作为方法调用时将上下文更改为 cat 对象: cat.sayCatName().
2. 动态上下文的回调函数
this 在 JS 中是一个强大的特性, 它允许根据调用函数的方式更改上下文. 通常, 上下文是调用发生的目标对象, 这使得代码更加自然, 就像这个物体发生了什么.
但是, 箭头函数会在声明上静态绑定上下文, 并且无法使其动态化, 但这种方式有坏也有好, 有时候我们需要动态绑定.
在客户端编程中, 将事件侦听器附加到 DOM 元素是一项常见的任务. 事件触发处理程序函数, 并将 this 作为目标元素, 这里如果使用箭头函数就不够灵活.
下面的示例尝试为这样的处理程序使用箭头函数:
在全局上下文中 this 指向 Windows. 当发生单击事件时, 浏览器尝试使用按钮上下文调用处理函数, 但箭头函数不会更改其预定义的上下文. this.innerhtml 相当于 Windows.innerHTML, 没有任何意义.
必须应用函数表达式, 该表达式允许根据目标元素更改 this:
当用户单击按钮时, 处理程序函数中的 this 指向 button. 因此这个问题. innerHTML = '已单击按钮'正确地修改按钮文本以反映已单击状态.
3. 调用构造函数
this 在构造调用中是新创建的对象. 当执行 newMyFunction() 时, 构造函数 MyFunction 的上下文是一个新对象: thisinstanceofMyFunction===true.
注意, 箭头函数不能用作构造函数. JavaScript 通过抛出异常隐式阻止这样做.
无论如何, this 是来自封闭上下文的设置, 而不是新创建的对象. 换句话说, 箭头函数构造函数调用没有意义, 而且是模糊的.
让我们看看如果尝试这样做会发生什么:
执行 newMessage('Hello World!'), 其中 Message 是一个箭头函数, JavaScript 抛出一个 TypeError 错误, Message 不能用作构造函数.
上面的例子可以使用函数表达式来修复, 这是创建构造函数的正确方法 (包括函数声明):
简写语法
箭头函数有一个很好的属性, 它可以省略参数圆括号 (), 块大括号 {}, 如果函数主体只有一条语句, 则返回. 这有助于编写非常短的函数.
作者的大学编程教授给学生一个有趣的任务: 编写 用 C 语言计算字符串长度的最短函数, 这是学习和探索新语言的好方式.
然而, 在实际应用程序中, 许多开发人员都会阅读代码. 最短的语法并不总是适合帮助你的同事即时了解该方法的用途.
在某种程度上, 简写的函数变得难以阅读, 所以尽量不要过度 wfget. 让我们看一个例子
multiply 返回两个数字的乘法结果或与第一个参数绑定的闭包, 以便以后的乘法运算.
该函数运行良好, 看起来很短. 但从一开始就很难理解它是做什么的.
为了使其更具可读性, 可以从箭头函数恢复可选花括号和 return 语句, 或使用常规函数:
在简短和冗长之间找到一个平衡点是很好的, 这样可以使代码更加直观.
总结
毫无疑问, 箭头函数是一个很好的补充. 当正确使用时, 它会使前面必须使用 .bind() 或试图捕获上下文的地方变得简单, 它还简化了代码.
某些情况下的优点会给其他情况带来不利. 当需要动态上下文时, 不能使用箭头函数: 定义方法, 使用构造函数创建对象, 在处理事件时从 this 获取目标.
来源: http://www.jianshu.com/p/414fecda9766