Home > Article > Web Front-end > Six barriers to JavaScript This
In view of the way this coquettish operation, the understanding of this is a timeless topic, this article attempts to nail it by breaking it into six pieces Stay with this annoying monster.
this is all about context.
To put it bluntly, this is to find the boss and the object (context object) that owns the current context (context).
Big bosses can be divided into six levels. The higher the level, the greater the power. This will only recognize the largest one.
The boss with the least power is a spare tire. Under normal circumstances, it is the global situation, and in the browser, it is the window; in the case of use strict, it is undefined.
function showThis () { console.log(this) } function showStrictThis () { 'use strict' console.log(this) } showThis() // window showStrictThis() // undefined
The boss of the second level puts it bluntly and is to find the dot in front of this function.
If the function that uses this belongs to a context object, then this context object is bound to this.
For example, in the following example, boss is the context object of returnThis, or returnThis belongs to boss.
var boss = { name: 'boss', returnThis () { return this } } boss.returnThis() === boss // true
Be careful with the following example. Can you come up with the answer?
var boss1 = { name: 'boss1', returnThis () { return this } } var boss2 = { name: 'boss2', returnThis () { return boss1.returnThis() } } var boss3 = { name: 'boss3', returnThis () { var returnThis = boss1.returnThis return returnThis() } } boss1.returnThis() // boss1 boss2.returnThis() // ? boss3.returnThis() // ?
The answer is boss1 and window Oh, did you guess it right?
Just look at the function that uses this.
In boss2.returnThis, the function that uses this is boss1.returnThis, so this is bound to boss1;
In boss3.returnThis, the function that uses this is returnThis, so this is bound to Order a spare tire.
How to bind this to boss2?
var boss1 = { name: 'boss1', returnThis () { return this } } var boss2 = { name: 'boss2', returnThis: boss1.returnThis } boss2.returnThis() //boss2
Yes, as long as the function using this belongs to boss2.
The bosses of the third level are Object.prototype.call and Object.prototype.apply, which can specify this through parameters. (Note that this cannot be directly assigned, this = 2 will report a ReferenceError.)
function returnThis () { return this } var boss1 = { name: 'boss1' } returnThis() // window returnThis.call(boss1) // boss1 returnThis.apply(boss1) // boss1
The boss of the fourth level is Object.prototype.bind, he Not only does it provide permanent binding through a new function, it also overrides the commands of the third-level boss.
function returnThis () { return this } var boss1 = { name: 'boss1'} var boss1returnThis = returnThis.bind(boss1) boss1returnThis() // boss1 var boss2 = { name: 'boss2' } boss1returnThis.call(boss2) // still boss1
A place that is easier to ignore and bind this is new. When we new a function, this will be automatically bound to the new object, and then the function will be called. It overrides bind 's binding.
function showThis () { console.log(this) } showThis() // window new showThis() // showThis var boss1 = { name: 'boss1' } showThis.call(boss1) // boss1 new showThis.call(boss1) // TypeError var boss1showThis = showThis.bind(boss1) boss1showThis() // boss1 new boss1showThis() // showThis
The last powerful boss is the arrow function of ES2015. This in arrow functions is no longer glamorous. It is permanently sealed into the current lexical scope. It is called Lexical this and can be determined before the code is run. No other big guy can cover it.
The advantage of this is that it is convenient to use the current scope of this of the callback function without fear of causing confusion.
So for the arrow function, just look at where it is created.
If you are interested in the lexical scope implemented by V8, you can take a look here.
function callback (cb) { cb() } callback(() => { console.log(this) }) // window var boss1 = { name: 'boss1', callback: callback, callback2 () { callback(() => { console.log(this) }) } } boss1.callback(() => { console.log(this) }) // still window boss1.callback2(() => { console.log(this) }) // boss1
You need to pay attention to the following weird usage:
var returnThis = () => this returnThis() // window new returnThis() // TypeError var boss1 = { name: 'boss1', returnThis () { var func = () => this return func() } } returnThis.call(boss1) // still window var boss1returnThis = returnThis.bind(boss1) boss1returnThis() // still window boss1.returnThis() // boss1 var boss2 = { name: 'boss2', returnThis: boss1.returnThis } boss2.returnThis() // boss2
If you don’t know why it is boss2 in the end, continue to understand "For arrow functions, just look at where it is created" sentence.
The above is the content of the six hurdles of JavaScript This. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!