这些年来,ES6 将 JS 的可用性提升到一个新的水平时: 箭头函数、类等等,这些都很棒。

箭头函数是最有价值的新功能之一,有很多好文章描述了它的上下文透明性和简短的语法。

但每个事务都有两面。通常,新特性会带来一些混乱,其中之一就是箭头函数被误导了。本文将介绍一些场景,在这些场景中,你应该绕过箭头函数,转而使用良好的旧函数表达式或较新的简写语法。并且要注意缩短代码,因为这会影响代码的可读性。

1.定义对象上的方法

在JS中,方法是存储在对象属性中的函数。当调用该方法时,this 将指向该方法所属的对象。

Object literal

由于箭头函数语法简短,所以使用它来定义方法是很有吸引力的,让咱们来试一试:const calculate = {

array: [1, 2, 3],

sum: () => {

console.log(this === window); // => true

return this.array.reduce((result, item) => result + item);

}

};

console.log(this === window); // => true

// Throws "TypeError: Cannot read property 'reduce' of undefined"

calculate.sum();

calculate.sum方法用箭头函数定义。 但是在调用时,calculate.sum() 会抛出一个TypeError,因为this.array 为undefined。

当调用calculate对象上的方法sum()时,上下文仍然是 window。之所以会发生这种情况,是因为箭头函数按词法作用域将上下文绑定到 window 对象。

执行this.array等同于window.array,它是undefined。

解决方法是使用常规函数表达式来定义方法。 this 是在调用时确定的,而不是由封闭的上下文决定的,来看看修复后的版本:const calculate = {

array: [1, 2, 3],

sum() {

console.log(this === calculate); // => true

return this.array.reduce((result, item) => result + item);

}

};

calculate.sum(); // => 6

因为sum是常规函数,所以在调用 calculate.sum() 时 this 是 calculate 对象。 this.array是数组引用,因此正确计算元素之和:6。

Object prototype

同样的规则也适用于在原型对象上定义方法。使用一个箭头函数来定义sayCatName方法,this 指向 windowfunction MyCat(name) {

this.catName = name;

}

MyCat.prototype.sayCatName = () => {

console.log(this === window); // => true

return this.catName;

};

const cat = new MyCat('Mew');

cat.sayCatName(); // => undefined

使用早期的方式定义函数表达式:function MyCat(name) {

this.catName = name;

}

MyCat.prototype.sayCatName = function() {

console.log(this === cat); // => true

return this.catName;

};

const cat = new MyCat('Mew');

cat.sayCatName(); // => 'Mew'

sayCatName常规函数在作为方法调用时将上下文更改为cat对象:cat.sayCatName()。

2. 动态上下文的回调函数

this 在JS中是一个强大的特性,它允许根据调用函数的方式更改上下文。通常,上下文是调用发生的目标对象,这使得代码更加自然,就像这个对象发生了什么。

但是,箭头函数会在声明上静态绑定上下文,并且无法使其动态化,但这种方式有坏也有好,有时候我们需要动态绑定。

在客户端编程中,将事件侦听器附加到DOM元素是一项常见的任务。事件触发处理程序函数,并将this作为目标元素,这里如果使用箭头函数就不够灵活。

下面的示例尝试为这样的处理程序使用箭头函数:const button = document.getElementById('myButton');

button.addEventListener('click', () => {

console.log(this === window); // => true

this.innerHTML = 'Clicked button';

});

在全局上下文中 this 指向 window。 当发生单击事件时,浏览器尝试使用按钮上下文调用处理函数,但箭头函数不会更改其预定义的上下文。this.innerHTML相当于window.innerHTML,没有任何意义。

必须应用函数表达式,该表达式允许根据目标元素更改 this:const button = document.getElementById('myButton');

button.addEventListener('click', function() {

console.log(this === button); // => true

this.innerHTML = 'Clicked button';

});

当用户单击按钮时,处理程序函数中的 this 指向 button。因此这个问题。innerHTML = 'Clicked button' 正确地修改按钮文本以反映已单击状态。

3.调用构造函数

this 在构造调用中是新创建的对象。当执行new MyFunction()时,构造函数MyFunction的上下文是一个新对象:this instanceof MyFunction === true。

注意,箭头函数不能用作构造函数。 JavaScript通过抛出异常隐式阻止这样做。

无论如何,this是来自封闭上下文的设置,而不是新创建的对象。换句话说,箭头函数构造函数调用没有意义,而且是模糊的。

让我们看看如果尝试这样做会发生什么:const Message = (text) => {

this.text = text;

};

// Throws "TypeError: Message is not a constructor"

const helloMessage = new Message('Hello World!');

执行new Message('Hello World!'),其中Message是一个箭头函数,JavaScript抛出一个 TypeError 错误,Message不能用作构造函数。

上面的例子可以使用函数表达式来修复,这是创建构造函数的正确方法(包括函数声明):const Message = function(text) {

this.text = text;

};

const helloMessage = new Message('Hello World!');

简写语法

箭头函数有一个很好的属性,它可以省略参数圆括号()、块大括号{},如果函数主体只有一条语句,则返回。这有助于编写非常短的函数。

原文作者的大学编程教授给学生一个有趣的任务:编写 用C语言计算字符串长度的最短函数,这是学习和探索新语言的好方式。

然而,在实际应用程序中,许多开发人员都会阅读代码。 最短的语法并不总是适合帮助你的同事即时了解该方法的用途。

在某种程度上,简写的函数变得难以阅读,所以尽量不要过度使用。让各位们看一个例子const multiply = (a, b) => b === undefined ? b => a * b : a * b;

const double = multiply(2);

double(3); // => 6

multiply(2, 3); // => 6

multiply返回两个数字的乘法结果或与第一个参数绑定的闭包,以便以后的乘法运算。

该函数运行良好,看起来很短。但从一开始就很难理解它是做什么的。

为了使其更具可读性,可以从箭头函数恢复可选花括号和return语句,或使用常规函数:function multiply(a, b) {

if (b === undefined) {

return function(b) {

return a * b;

}

}

return a * b;

}

const double = multiply(2);

double(3); // => 6

multiply(2, 3); // => 6

在简短和冗长之间找到一个平衡点是很好的,这样可以使代码更加直观。

总结

毫无疑问,箭头函数是一个很好的补充。当正确使用时,它会使前面必须使用.bind()或试图捕获上下文的地方变得简单,它还简化了代码。

经过事件还是箭头 html,箭头函数不合适什么场景?相关推荐

  1. js map 箭头_JS异常函数之箭头函数

    来源:logrocket作者:Maciej Cieślar 译者:前端小智 为了保证的可读性,本文采用意译而非直译. 在JS中,箭头函数可以像普通函数一样以多种方式使用.但是,它们一般用于需要匿名函数 ...

  2. js map 箭头_JS异常函数之-箭头函数

    来源:logrocket 作者:Maciej Cieślar 译者:前端小智 为了保证的可读性,本文采用意译而非直译. 在JS中,箭头函数可以像普通函数一样以多种方式使用.但是,它们一般用于需要匿名函 ...

  3. 由c#事件监听、回调函数引发观察者模式

    由c#事件监听.回调函数引发观察者模式 事件监听: C#中的事件,可以简单的理解为类或者对象发生了一件事,并且把这件事通知给了其他的类或者对象,其他的类或者对象可以根据事件的消息有所反应. 这非常类似 ...

  4. WPF 委托和事件实现子窗口回调函数, 实时刷新主窗口控件

    注册窗口事件, 实时刷新主窗口控件 通常用于子窗口修改数据后实时刷新主窗口的ListView控件的场景 这个demo实现的功能是子窗口的TextBox中的数据实时显示到主窗口的Label 运行效果: ...

  5. Vue.js:vue指令(给标签属性赋Vue变量v-bind,绑定事件 v-on)vue事件处理函数中, 拿到事件对象,6个事件修饰符

    1. 给标签属性赋Vue变量v-bind 在vue中,v-bind指令可以动态的给标签的属性设置值, 语法:v-bind:属性名="vue变量" 简写::属性名="vue ...

  6. 如何在UITableViewCell的中添加向右箭头和箭头前的文本

    如何在UITableViewCell的中添加向右箭头和箭头前的文本 2014-10-01 20:12:26来源:CSDN作者:u01362386710391人点击 1.首先说的是添加向右的箭头,这个很 ...

  7. bind函数作用、应用场景以及模拟实现

    bind函数 bind 函数挂在 Function 的原型上 Function.prototype.bind 创建的函数都可以直接调用 bind,使用: function func(){console ...

  8. 箭头函数与普通函数,以及使用场景

    链接 箭头函数和普通函数的区别如下. 普通函数:根据调用我的人(谁调用我,我的this就指向谁) 箭头函数:根据所在的环境(我再哪个环境中,this就指向谁) 一针见血式总结: 普通函数中的this: ...

  9. MATLAB箭头绘制 arrow3 函数与 quiver3 函数的实用教程

    MATLAB 的 arrow3 函数可以方便地在 figure 窗口中绘制箭头,效率也还可以,这里简单介绍其基本使用方法以便读者参考.对于一般的使用场景而言arrow3的使用十分简单方便.但是,arr ...

  10. Latex tips 手写转+Latex空格+Latex箭头+Latex分段函数(大括号)+各向省略号+正规子群符号+恒等符号+字体大小

    Latex tips: 手写转 绘画转latex 常用数学符号 手写不易识别的 空格   两个quad空格 a \qquad b quad空格 a \quad b 大空格 a\ b 中等空格 a\;b ...

最新文章

  1. Python实用小工具了解一下,总有一款是你需要的
  2. 命令行的基本使用方法(权限)
  3. CentOS安装 Go 环境
  4. wxPython布局管理
  5. 调用百度报Cannot read property ‘lng‘ of null错误
  6. 计算机专业英语主要句型及翻译技巧,计算机专业英语单词及翻译等技巧-20210420072747.ppt-原创力文档...
  7. 如何使用IDEA自带的数据库连接工具连接达梦数据库,IDEA连接DM(达梦)数据库
  8. C++小游戏数字炸弹
  9. 基于springboot智慧养老手表管理系统
  10. wifi+遥控器+android,基于安卓手机wifi的智能遥控器设计
  11. android+cast+sdk,如何使用Android发现Chromecast设备?
  12. 跨月作废发票,红字冲红注意事项 如何整理上交发票
  13. 【turtle】画一朵漂亮的玫瑰花,真的很漂亮
  14. Python撩妹实战——教你用微信每天给女朋友说晚安
  15. linux下添加新用户,并赋予root权限
  16. 通过左旋和右旋来实现搜索二叉树的自平衡
  17. 硬盘引导服务器,Windows 7实战之为本机引导部署虚拟硬盘
  18. 百度编辑器Editor 1.4.3.2 asp.net版最新使用方法
  19. 摄影测量航带设计程序
  20. 高斯 默克托投影知识

热门文章

  1. java8新特性—— Lambda来由
  2. Oracle批量、大量Update方法总结
  3. Java 注解Annotation总结二
  4. Http和Https网络同步请求httpclient和异步请求async-http-client
  5. 段上的等待事件 —— enq: HW - contention(oracle)
  6. Facebook全面实施GDPR 用户Pages页面被随意锁定
  7. C语言基础四(敲打键盘、寻找资料,循环语句)请一个个字读,助于您的学会机率...
  8. 你的服务器安全么?--服务器防渗透(1)
  9. BigPipe为什么可以节省时间?
  10. authorware学习