Home  >  Article  >  Web Front-end  >  Six barriers to JavaScript This

Six barriers to JavaScript This

黄舟
黄舟Original
2017-02-21 11:17:371384browse



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.

First of all

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 first level: the end of the world

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 second level: turning stone into gold

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.

Third level: fingertips for marriage

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

Fourth level: Each other

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

The fifth layer: There is a universe inside

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 sixth level: mountains of military orders

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)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn