A collection of code snippets explaining:
thisbind- arrow functions
A collection of code snippets explaining:
thisbind| var name = 'globalName'; | |
| const obj = { | |
| name: 'myName', | |
| sayName: function () { console.log(this.name);} | |
| } | |
| obj.sayName(); | |
| // output: myName | |
| const say = obj.sayName; | |
| // we are merely storing the function | |
| // the value of `this` isn't magically transferred | |
| say(); | |
| // output: globalName | |
| // now because this function is executed in global scope | |
| // `this` will refer to the global var | |
| const boundSay = obj.sayName.bind(obj); | |
| // now the value of this is bound to the obj object | |
| boundSay(); | |
| // output: myName | |
| // Now this will refer to the name in the obj object: 'myName' | |
| const obj2 = { | |
| name: "hisName" | |
| }; | |
| const boundSay2 = obj.sayName.bind(obj2); | |
| // obj2 has no function to say its name | |
| // and we want to share the same function from obj | |
| boundSay2(); | |
| // output: hisName | |
| // what happened? | |
| // `.bind` is creating a new function, with the given context | |
| console.log(boundSay == obj.sayName) | |
| // output: false | |
| // reading | |
| // 1. https://stackoverflow.com/questions/2236747/use-of-the-javascript-bind-method | |
| // 2. https://gist.github.com/zcaceres/2a4ac91f9f42ec0ef9cd0d18e4e71262 |
| this.age = 3; | |
| const sayAge = () => { | |
| console.log(this.age) | |
| } | |
| sayAge() | |
| // output: 3 | |
| // An arrow function `() => {}` does not have its own `this` | |
| // (and `arguments`, `super` or `new.target`). | |
| // so calling add() is looking up `this.age` in upper scope | |
| function Person() { | |
| this.age = 30; | |
| sayAge(); | |
| } | |
| const p = new Person(); | |
| // output: 3 | |
| // instead of 30 | |
| // It proves that the arrow function is looking up `this.age` in a consistent manner, | |
| // by always pointing to the context when it first *created*. | |
| // how to fix | |
| function Person2() { | |
| this.age = 30; | |
| const sayAge2 = () => { | |
| console.log(this.age); | |
| } | |
| // define the arrow function in the context that we need it | |
| sayAge2(); | |
| } | |
| const p2 = new Person2(); | |
| // output: 30 | |
| // Following is a popular usage to create arrow function in class | |
| // A1 | |
| class A1 { | |
| constructor() { | |
| this.counter = 0; | |
| } | |
| handleClick1 = () => { | |
| this.counter++; | |
| } | |
| handleClick2() { | |
| this.counter++; | |
| } | |
| } | |
| // class A1 will be transpiled into | |
| // class A2 by Babel | |
| class A2 { | |
| constructor() { | |
| this.handleClick1 = () => { | |
| this.counter++; | |
| }; | |
| this.counter = 0; | |
| } | |
| handleClick2() { | |
| this.counter++; | |
| } | |
| } | |
| // The original intention is to declare an instance method by an arrow function | |
| // `handleClick1`, however, the arrow function is moved into constructor after tranpiling | |
| // as an instance member. | |
| // | |
| // The arrow function `handleClick1` is not in the prototype, with two shortcomings: | |
| // 1. performance could be problematic since all instances create their own members. | |
| // 2. can not be called by `super` since they are inside constructors. | |
| // > You should only bind with .bind() or arrow function a method if you’re going to pass it around. | |
| // reading | |
| // 1. https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1 |