Common functions
Here's the normal function.
function add(x, y) { return x + y;}
Each normal function is called when it is equivalent to having a this parameter passed in.
The intrinsic function This is not an external function that is passed in this, which is equivalent to and outside the this interval.
function outer() { function inner() { console.log(this); // window } console.log(this); // ‘outer‘ inner();}outer.call(‘outer‘);
Equivalent:
function outer(_this) { function inner(_this) { console.log(_this); // undefined } console.log(_this); // ‘outer‘ inner(undefined);}outer(‘outer‘);
Arrow functions
const add = (x, y) => { return x + y;};
If you use the arrow function, the inner function of this and the outside is consistent:
function outer() { const inner = () => { console.log(this); // ‘outer‘ }; console.log(this); // ‘outer‘ inner();}outer.call(‘outer‘);
The This of the arrow function is not affected by the call method, it is always related to the position of the arrow function:
This is where it is located (that is, the scope), and the This in the arrow function is pointing to WHO.
function ordinary() { const arrow = () => this; console.log(arrow.call(‘goodbye‘)); // ‘hello‘}ordinary.call(‘hello‘);
Common functions as a method
If a function assigns a value to a property, it becomes a method:
const obj = { prop: function () {}};
Methods are called by:
obj.prop(x, y)
Equivalent:
obj.prop.call(obj, x, y)
Trap
1 callback function inside with this
Callback inside Execution (A), you find logstatus cannot access. This is because this is blocked.
performCleanup() { cleanupAsync() .then(function () { this.logStatus(‘Done‘); // (A) });}
You should use the arrow function:
performCleanup() { cleanupAsync() .then(() => { this.logStatus(‘Done‘); });}
2 Map method inside with this
Similarly, this is not accessible to company and name
prefixNames(names) { return names.map(function (name) { return this.company + ‘: ‘ + name; // (A) });}
Use the arrow function:
// Inside a class or an object literal:prefixNames(names) { return names.map( name => this.company + ‘: ‘ + name);}
3 using functions as callbacks
class UiComponent { constructor(name) { this.name = name; const button = document.getElementById(‘myButton‘); button.addEventListener(‘click‘, this.handleClick); // (A) } handleClick() { console.log(‘Clicked ‘+this.name); // (B) }}
Switch
class UiComponent { constructor(name) { this.name = name; const button = document.getElementById(‘myButton‘); button.addEventListener( ‘click‘, this.handleClick.bind(this)); // (A) } handleClick() { console.log(‘Clicked ‘+this.name); }}
The bind function makes it impossible for a normal function call to modify this:
function returnThis() { return this;}const bound = returnThis.bind(‘hello‘);bound(); // ‘hello‘bound.call(undefined); // ‘hello‘
Keep the right approach
1 with Eslint's rules:no-invalid-this
Avoid having this within the normal function, usually within the method using this or the arrow function
2 Do not take this as a parameter
Because then you can't use the arrow function.
beforeEach(function () { this.addMatchers({ // access API object toBeInRange: function (start, end) { ··· } });});
can easily be rewritten:
beforeEach(api => { api.addMatchers({ toBeInRange(start, end) { ··· } });});
Original link: http://2ality.com/2017/12/alternate-this.html
Author/Public Number: front-end Crazy (a group of front-line programmers who love to maintain, want to change the world with the front end.) )
From for notes (Wiz)
Mastering JavaScript Basics-New ideas for understanding this keyword