• Arrow functions and the ‘this’ keyword


    原文: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?

     
    // Test it here: https://jsfiddle.net/maasha/x7wz1686/
    var bunny = {
      name: 'Usagi',
      showName: function() {
        alert(this.name);
      }
    };
    
    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?

     
    // Test it here: https://jsfiddle.net/maasha/z65c1znn/
    var bunny = {
      name: 'Usagi',
      tasks: ['transform', 'eat cake', 'blow kisses'],
      showTasks: function() {
        this.tasks.forEach(function(task) {
          alert(this.name + " wants to " + task);
        });
      }
    };
    
    bunny.showTasks();
    // [object Window] wants to transform
    // [object Window] wants to eat cake
    // [object Window] wants to blow kisses
    
    // 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.

     
    // Test it here: https://jsfiddle.net/maasha/g278gjtn/
    var standAloneFunc = function(){
      alert(this);
    }
    
    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’.

     
    // Test it here: https://jsfiddle.net/maasha/3mu5r6vg/
    var bunny = {
      name: 'Usagi',
      tasks: ['transform', 'eat cake', 'blow kisses'],
      showTasks: function() {
        var _this = this;
        this.tasks.forEach(function(task) {
          alert(_this.name + " wants to " + task); 
        });
      }
    };
    
    bunny.showTasks();
    // Usagi wants to transform
    // Usagi wants to eat cake
    // Usagi wants to blow kisses
    

      

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

     
    // Test it here: https://jsfiddle.net/maasha/u8ybgwd5/
    var bunny = {
      name: 'Usagi',
      tasks: ['transform', 'eat cake', 'blow kisses'],
      showTasks: function() {
        this.tasks.forEach(function(task) {
          alert(this.name + " wants to " + task);
        }.bind(this));
      }
    };
    
    bunny.showTasks();
    // Usagi wants to transform
    // Usagi wants to eat cake
    // 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:

     
    // Test it here: https://jsfiddle.net/maasha/che8m4c1/
    
    var bunny = {
      name: 'Usagi',
      tasks: ['transform', 'eat cake', 'blow kisses'],
      showTasks() {
        this.tasks.forEach((task) => {
          alert(this.name + " wants to " + task);
        });  
      }
    };
    
    bunny.showTasks();
    // Usagi wants to transform
    // Usagi wants to eat cake
    // 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.

  • 相关阅读:
    thinkphp3.2v
    ng-select 下拉的两种方式
    angular的时间指令 以及防止闪烁问题
    angularjs中的几种工具方法
    运用正则+replace+substring将一段英语的字母大写 angurlar运用自定义指令filter完成首字母大写
    angularjs bind与model配合双向绑定 表达式方法输出
    ajax跨域问题
    团队作业一
    校外实习报告(四)
    校外实习报告(三)
  • 原文地址:https://www.cnblogs.com/oxspirt/p/10220104.html
Copyright © 2020-2023  润新知