Why cannot use lambda to define prototype function

前端 未结 3 509
一个人的身影
一个人的身影 2021-01-11 13:24

Can someone please explain why defining a prototype function with lambda expression doesn\'t work? I thought this must be asked before but couldn\'t find it.



        
相关标签:
3条回答
  • 2021-01-11 14:03

    One of the chief features of arrow functions is that they close over the this from the context in which they're created; they don't get it based on how they're called like other functions do. So...

    // ...whatever `this` is *here*
    Book.prototype.printTitle2 = () => {
        // ...is what `this` will be *here*
        console.log(this.title);
    };
    

    But your function relies on this varying depending on how it's called.

    This just isn't a use-case for arrow functions. Use a normal function:

    Book.prototype.printTitle2 = function() {
        console.log(this.title);
    };
    

    Or better yet, use the new class syntax:

    class Book {
        constructor(title, year) {
            this.title = title;
            this.year = year;
        }
    
       printTitle2() {
            console.log(this.title);
        }
    }
    
    0 讨论(0)
  • 2021-01-11 14:13

    The Arrow function would resolve the context this belongs to the scope where the function was defined. I believe you have defined that function in window scope. So the this will point to window in your function.

    You can use normal anonymous function here. And we have to be careful while using arrow functions.

    0 讨论(0)
  • 2021-01-11 14:16

    In addition to @t-j-crowder's answer, I wanted to leave a test case (mocha assert) which you can use to visualize which is not working.

    Also you can read more about the scope of arrow functions here: You Don't Know JS by Kyle Simpson, who explains this in detail.

    Basically, an arrow function's this points to the surrounding context of the current context, which comes in handy if you have enclosing functions. What it does is basically doing the var self = this; thing.

    Or as Kyle says:

    [...] Lexical this in the arrow function callback in the previous snippet now points to the same value as in the enclosing makeRequest(..) function. In other words, => is a syntactic stand-in for var self = this.

    In cases where var self = this (or, alternatively, a function .bind(this) call) would normally be helpful, => arrow functions are a nicer alternative operating on the same principle. [...]

    You can test it yourself with my gist: https://gist.github.com/jay-bricksoft/96738dd8a48ceb9f517e914b834cc1ee

    In my test case this was the output:

    Lambda
        function(){}
          √ should equal function´s type
          1) should have equal context as function
          2) should be able to be used as constructor
      1 passing (39ms)
      2 failing
      1) Lambda function(){} should have equal context as function:
          AssertionError: 'undefined' == 'string'
          + expected - actual
          -undefined
          +string
    
          at Context.<anonymous> (test\index.js:29:14)
      2) Lambda function(){} should be able to be used as constructor:
         TypeError: construct_l is not a constructor
          at Context.<anonymous> (test\index.js:34:20)
    

    EDIT: added example / reference to Kyle Simpson's "You Don't Know ES6" https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond

    0 讨论(0)
提交回复
热议问题