Objective
There are no block-level scopes (ES6) in JavaScript, which are scoped into function scope and global scope. And, you can think that the global scope is actually the function scope of the window function, we write the JS code, are stored in the window function (this is a hypothesis), that is, JavaScript only function scope (assuming the premise).
What is the scope
Scope is a box, the inside of the box variables can only be used in the current box, scope boxes can be nested, the internal box variables are not visible to the parent box, because the box closed them and the box is opaque, but the box can see the parent box inside the defined variables, Because the inner box is in the same space as the parent variable, they see each other. Just like the box model in CSS.
The above diagram is divided into 3-level scope, global scope, Foo function scope, bar function scope, we can clearly see the scope of the three-level scope of each.
What is this?
What do we often use this,this to represent? This is the environment context that represents the execution of the current method, and what is the context of the environment, in layman's name, who called the function, who is the context of the function. For example:
function run () { Console.log (this)}var o = { run:run}run () /// Window object o.run // o object
In the above code, run is a function that first executes run () returns the Window object, why? As we have already said, the variable defined by VAR will be hung in the Window object by default, so function-defined functions will be hung to the Window object by default, and we are actually executing a function such as: Run () is the same as Window.run (), So, Window calls run, so this is the window for the function.
Note: This binding is generated when a function is called, not when the function is defined
var o = { ' red ', function () { Console.log (this . Color) }} var color = ' Blue 'var getColor =// redgetColor // Blue
The above code, We assign the O.getcolor method to a variable getcolor, and then we execute two separate methods, missing a different result, there is no doubt about O.getcolor, but the beginner may think GetColor return should also be red, but the fact is blue, which shows that th Is is generated when a function is called, because in the O.getcolor assignment statement, it is equivalent to a statement
var function () { Console.log (this. Color)}
O.getcolor returns this function and does not bind this, that is, GetColor is actually assigned a function, that is, this is bound at the time of the call, so the result is obtained.
Do not be blinded by the appearance
Look at the following code:
var o = { function () { setTimeout ()} (function () { Console.log (this) ) }}o.run () // Window Object
Above run the O.run method, output this in a second, the output of the Window object, beginners may doubt, O.run call when it is clearly under the O object ah, this should be O object Ah! Yes, there is a certain understanding of this, but the above case is the output of this in the callback function in the SetTimeout method, and this callback function executes in the form of FN (), which involves an asynchronous callback. As mentioned earlier, the direct execution function is equivalent to WINDOW.FN, so the window object is output.
Extension callbacks:
Callbacks are common functions for asynchronous operations, and in the example above, we can assume that settimeout is defined as
function setTimeout {Fun} () }settimeout(function () { Console.log (this )})
It can be seen that the fun is called directly, the output of this must be the Window object.
Violent binding this
Sometimes, we need to force this in a function to be an object, and we need to bind this at this time, here, there are 3 methods of violence: Call, apply, bind. Here's a simple demo to look at their usage.
varcolor = ' Blue 'varo ={color:' Red ', say:function(animal, beautiful) {Console.log ( This. Color + ' color ' + animal + (beautiful? ' Good looking ': ' not good to see ')) }}varsay=O.saysay (' Cat ',false)//blue color of the cat is not good to seeSay.call (O, ' cat ',true)//red color of the cat looks goodSay.apply (o, [' Cat ',true])//red color of the cat looks goodSay.bind (o) (' Cat ',true)//red color of the cat looks goodO.say.call (NULL, ' Cat ',false)//blue color of the cat is not good to see
We will add an O function to the say method, the say method receives two parameters, the first number of animals, the second is a Boolean value is not good looking, we still assign O.say to the variable say.
Say (' Cat ', false) returned the blue color as expected
Say.call (O, ' cat ', True), Say.apply (O, [' Cat ', True]), Say.bind (o) (' cat ', true) these three have all returned to red, and we are all violent bound this to the O object.
The first parameter of call and apply is to receive the object to be bound, that is, to tell the engine: ' I want to let the say method run in the environment of O object, you give me a help to the top ', the engine replied: ' Wrapped in me ', and then we're bound to succeed, next we need to pass parameters into the method, the call method is after the second parameter, in order to pass parameters to the method, the Apply method is different, the application method is in the second parameter in the form of an array of parameters passed to the method. The Bind method is a method in es5, and the purpose is to bind this pointer and return the function that is already bound, so the above three outputs a red
The same o.say is bound to null or undefined, and the engine is automatically bound to the Global object under window.
Advanced: Function Execution process
In the spirit of rookie ideas, and try to tell the simple function of the process behind the execution, there are errors please correct me.
function fn (A, b) { var c = 2; function f () {...}} var o = {}fn.call (O,1, ' OK ')
The function FN executes, will first produce a function activity object, this activity object is invisible to the outside, in this example, the FN function activity object First bound the this call of this point O, the assignment between the parameters formed the arguments object, and then carried out the initialization variable inside the function, Finally, the assignment procedure inside the function is executed. The process is as follows:
function fn (a = 1, b = ' OK ') { var c var f // After initialization of the active object, perform other operations within the function body, this variable promotion and function declaration promotion about C = 2 function () {...}}
Summarize
All in all, the function is the most important structure in JavaScript, and this is a pointer to the dynamic binding required in JavaScript and even in every high-level language. Ability general, the level is limited, if has the mistake, lightly sprays lightly scold.
This and function in JavaScript is explained