原文:https://medium.freecodecamp.org/learn-es6-the-dope-way-part-ii-arrow-functions-and-the-this-keyword-381ac7a32881

-----------------------------------------------------------

Welcome to Part II of Learn ES6 The Dope Way, a series created to help you easily understand ES6 (ECMAScript 6)!

So, what the heck is => ?

You’ve probably seen these strange Egyptian-looking hieroglyphics symbols here and there, especially in someone else’s code, where you’re currently debugging a ‘this’ keyword issue. After an hour of tinkering, you’re now roaming the Google search bar and stalking Stack Overflow. Sound familiar?

Together, let’s cover three topics in Learn ES6 The Dope Way Part II:

  • How the ‘this’ keyword relates to =>.
  • How to migrate functions from ES5 to ES6.
  • Important quirks to be aware of when using =>.

Arrow Functions

Arrow functions were created to simplify function scope and make using the ‘this’ keyword much more straightforward. They utilize the => syntax, which looks like an arrow. Even though I don’t think it needs to go on a diet, people call it “the fat arrow” (and Ruby enthusiasts may know it better as the “hash rocket” ) — something to be aware of.

How the ‘this’ keyword relates to Arrow Functions

Before we dive deeper into ES6 arrow functions, it’s important to first have a clear picture of what ‘this’ binds to in ES5 code.

If the ‘this’ keyword were inside an object’s method (a function that belongs to an object), what would it refer to?

 
  1. // Test it here: https://jsfiddle.net/maasha/x7wz1686/
  2. var bunny = {
  3. name: 'Usagi',
  4. showName: function() {
  5. alert(this.name);
  6. }
  7. };
  8.  
  9. bunny.showName(); // Usagi

  

Correct! It would refer to the object. We’ll get to why later on.

Now what about if the ‘this’ keyword were inside of method’s function?

 
  1. // Test it here: https://jsfiddle.net/maasha/z65c1znn/
  2. var bunny = {
  3. name: 'Usagi',
  4. tasks: ['transform', 'eat cake', 'blow kisses'],
  5. showTasks: function() {
  6. this.tasks.forEach(function(task) {
  7. alert(this.name + " wants to " + task);
  8. });
  9. }
  10. };
  11.  
  12. bunny.showTasks();
  13. // [object Window] wants to transform
  14. // [object Window] wants to eat cake
  15. // [object Window] wants to blow kisses
  16.  
  17. // please note, in jsfiddle the [object Window] is named 'result' within inner functions of methods.

  

What did you get? Wait, what happened to our bunny…?

 
 

Ah, did you think ‘this’ refers to the method’s inner function?

Perhaps the object itself?

You are wise to think so, yet it is not so. Allow me to teach you what the coding elders had once taught me:

Coding Elder: “Ah yes, the code is strong with this one. It is indeed practical to think that the ‘this’ keyword binds to the function but the truth is, ‘this’ has now fallen out of scope…It now belongs to…”, he pauses as if experiencing inner turmoil, “the window object.

That’s right. That’s exactly how it happened.

Why does ‘this’ bind to the window object? Because ‘this’, always references the owner of the function it is in, for this case — since it is now out of scope — the window/global object.

When it is inside of an object’s method — the function’s owner is the object. Thus the ‘this’ keyword is bound to the object. Yet when it is inside of a function, either stand alone or within another method, it will always refer to the window/global object.

 
  1. // Test it here: https://jsfiddle.net/maasha/g278gjtn/
  2. var standAloneFunc = function(){
  3. alert(this);
  4. }
  5.  
  6. standAloneFunc(); // [object Window]

  

But why…?

This is known as a JavaScript quirk, meaning something that just happens within JavaScript that isn’t exactly straightforward and it doesn’t work the way you would think. This was also regarded by developers as a poor design choice, which they are now remedying with ES6's arrow functions.

Before we continue, it’s important to be aware of two clever ways programmers solve the ‘this’ problem within ES5 code, especially since you will continue to run into ES5 for awhile (not every browser has fully migrated to ES6 yet):

#1 Create a variable outside of the method’s inner function. Now the ‘forEach’ method gains access to ‘this’ and thus the object’s properties and their values. This is because ‘this’ is being stored in a variable while it is still within the scope of the object’s direct method ‘showTasks’.

 
  1. // Test it here: https://jsfiddle.net/maasha/3mu5r6vg/
  2. var bunny = {
  3. name: 'Usagi',
  4. tasks: ['transform', 'eat cake', 'blow kisses'],
  5. showTasks: function() {
  6. var _this = this;
  7. this.tasks.forEach(function(task) {
  8. alert(_this.name + " wants to " + task);
  9. });
  10. }
  11. };
  12.  
  13. bunny.showTasks();
  14. // Usagi wants to transform
  15. // Usagi wants to eat cake
  16. // Usagi wants to blow kisses

  

#2 Use bind to attach the ‘this’ keyword that refers to the method to the method’s inner function.

 
  1. // Test it here: https://jsfiddle.net/maasha/u8ybgwd5/
  2. var bunny = {
  3. name: 'Usagi',
  4. tasks: ['transform', 'eat cake', 'blow kisses'],
  5. showTasks: function() {
  6. this.tasks.forEach(function(task) {
  7. alert(this.name + " wants to " + task);
  8. }.bind(this));
  9. }
  10. };
  11.  
  12. bunny.showTasks();
  13. // Usagi wants to transform
  14. // Usagi wants to eat cake
  15. // Usagi wants to blow kisses

  

And now introducing…Arrow functions! Dealing with ‘this’ issue has never been easier and more straightforward! The simple ES6 solution:

 
  1. // Test it here: https://jsfiddle.net/maasha/che8m4c1/
  2.  
  3. var bunny = {
  4. name: 'Usagi',
  5. tasks: ['transform', 'eat cake', 'blow kisses'],
  6. showTasks() {
  7. this.tasks.forEach((task) => {
  8. alert(this.name + " wants to " + task);
  9. });
  10. }
  11. };
  12.  
  13. bunny.showTasks();
  14. // Usagi wants to transform
  15. // Usagi wants to eat cake
  16. // Usagi wants to blow kisses

  

While in ES5 ‘this’ referred to the parent of the function, in ES6, arrow functions use lexical scoping — ‘this’ refers to it’s current surrounding scope and no further. Thus the inner function knew to bind to the inner function only, and not to the object’s method or the object itself.

Arrow functions and the ‘this’ keyword的更多相关文章

  1. 《理解 ES6》阅读整理:函数(Functions)(四)Arrow Functions

    箭头函数(Arrow Functions) 就像名字所说那样,箭头函数使用箭头(=>)来定义函数.与传统函数相比,箭头函数在多个地方表现不一样. 箭头函数语法(Arrow Function Sy ...

  2. JavaScript ES6 Arrow Functions(箭头函数)

    1. 介绍 第一眼看到ES6新增加的 arrow function 时,感觉非常像 lambda 表达式. 那么arrow function是干什么的呢?可以看作为匿名函数的简写方式. 如: var ...

  3. ES6 In Depth: Arrow functions

    Arrows <script language="javascript"> <!-- document.bgColor = "brown"; ...

  4. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  5. ES6 箭头函数(Arrow Functions)

    ES6 箭头函数(Arrow Functions) ES6 可以使用 "箭头"(=>)定义函数,注意是函数,不要使用这种方式定义类(构造器). 一.语法 具有一个参数的简单函 ...

  6. arrow functions 箭头函数

    ES6里新增加的,与普通方法不同的地方 1.this 的对象在定义函数的时候确定了,而不是在使用的时候才决定 2.不可以使用 new  ,也就不能当构造函数 3.this 的值一旦确定无法修改     ...

  7. 箭头函数 Arrow Functions/////////////////////zzz

    箭头符号在JavaScript诞生时就已经存在,当初第一个JavaScript教程曾建议在HTML注释内包裹行内脚本,这样可以避免不支持JS的浏览器误将JS代码显示为文本.你会写这样的代码: < ...

  8. ES6箭头函数(Arrow Functions)

    ES6可以使用“箭头”(=>)定义函数,注意是函数,不要使用这种方式定义类(构造器). 一.语法 1. 具有一个参数的简单函数 var single = a => a single('he ...

  9. 深入浅出ES6(七):箭头函数 Arrow Functions

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 箭头符号在JavaScript诞生时就已经存在,当初第一个JavaScript教 ...

随机推荐

  1. 并发编程(二):全视角解析volatile

    一.目录 1.引入话题-发散思考 2.volatile深度解析 3.解决volatile原子性问题 4.volatile应用场景 二.引入话题-发散思考 public class T1 { /*vol ...

  2. 阻止新的csproj工程的dll引用继承

    VisualStudio传统的csproj工程中,引用是没有继承功能的.例如,对于如下一个引用关系 App引用Assembly 1 Assembly 1引用Assembly 2 程序App在没有添加A ...

  3. 使用filezilla server搭建FTP服务器

    参考文献 http://www.pc6.com/infoview/Article_51961_all.html 背景 需要在内网环境下搭建一个FTP服务器,查阅相关资料发现使用filezilla se ...

  4. WinForm多线程实现HTTP网络检测工具

    一.背景描述与课程介绍 明人不说暗话,跟着阿笨一起玩WinForm.本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的一部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高 ...

  5. [web.config]如何灵活使用配置文件

    摘要 在实际项目中,经常遇到比较多的环境,比如开发环境,测试环境,生产环境.对于这些环境,可能会有不同接口调用,不同的数据库连接字符串等等.那么该如何实现不同环境的参数快速切换呢?当然,最笨的方式就是 ...

  6. java链表知识点总结

    下面是一个Link类定义的一部分.它包含了一些数据和下一个链结点的引用: ? 1 2 3 4 5 class Link {     public int data;     public int id ...

  7. C#编程(三十)----------泛型结构,泛型方法,泛型委托

    泛型结构 泛型结构和泛型类几乎是一直的,只是泛型结构没有继承的特性..NET平台提供的一个泛型结构是(可空类型)Nullablle<T>.可空类型的引入,主要是为了解决数据库语言中的数字与 ...

  8. 在Android工程中加入AIDL文件时,gen目录生成的文件报错-问题解决

    from://http://blog.csdn.net/watt520/article/details/10099047 今天在弄清除缓存的东东,按照网上别人的方法,创建了一个AIDL文件,这个时候发 ...

  9. 批量生成protoBuf到cs文件

    color 0A && echo off rem protoc程序名set "PROTOC_EXE=protoc.exe"rem .proto文件名::set &q ...

  10. POST 和 PUT 方法区别

        Http定义了与 服务器的交互方法,其中除了一般我们用的最多的GET,POST 其实还有PUT和DELETE 根据RFC2616标准(现行的HTTP/1.1)其实还有OPTIONS,GET,H ...