An abstract problem in the actual scene
What does the following this point to?
var a = { function() { Console.log (this); }, function() { varthis. b; C (); } }; A.B (); A.F ();
The first this points to a, and the second this points to window. (Did you do the right thing?)
Second, the problem of variable replication in JavaScript
Variable copy divided into value copy and reference type data copy
When one variable copies the base type data value to another variable, the other variable holds a copy of its own data value in the memory it occupies.
When a variable copies a reference type data value to another variable, it essentially replicates a pointer variable that points to the object in the heap memory, and the two variables point to the same object after copying.
The basic data types in ES5 include string, number, null, Undefined, Boolean
Reference types include array, REGEXP, Date, function, and so on
(Basic Package Type: String, Boolean, number; single built-in object: Global, Math)
Third, function
The way a function is created: a function declaration, a function expression, created by a function constructor, which accepts any number of arguments, and the last parameter is always considered a function body.
(Example: New Function ("Num1", "num2", "return Num1+num2"))
A function declaration has a process of declaring an elevation, which, when loaded with data into the execution environment, takes precedence over the function declaration, ensuring that it is available before any code is executed, whereas the function expression is in the parser
Execution to the code line where it is located is parsed.
var condition = false; Console.log (Afun),//undefined if (condition) { function afun (num) { return num +; } } else { function afun (num) { return num + $; } }
The above code, the function call has not been judged before, so there is no afun function
var condition = false; if (condition) { function afun (num) { return num +; } } else { function afun (num) { return num + $; } } Console.log (Afun (100));//300
There is no concept of block-level scope in JS, the above code can be called normally
JS in the function is also an object, the function name is a pointer, so when the function name of a function is copied to another variable, this variable also points to the function
if (condition) {var bfun = function (num) { return num +;} } else { var bfun = function (num) { return num + $; } } var cfun = Bfun; Bfun = null;// console.log (bfun (100));//Error Console.log (Cfun (200));//400
After validating a copy of the function, the assigned variable and the assigned variable point to the same function, and the function expression and function declaration are the same as the functions defined in the copy, and the two variables point to the same function after copying.
After copying, adding a new Bfun, the new Bfun overrides the original Bfun,cfun also changed, indicating that the assigned variable and the assigned variable point to the same function.
function Bfun (num) { return num + $; } var cfun = bfun;function bfun (num) { return num*1000;}; Console.log (bfun);//100000 Console.log (Cfun (200));//200000
But when using the form of a function expression (in the Bfun function defined by the function expression, Bfun is also a global variable, where the variable is not defined with Var, and the canonical notation should be prefixed with Var) once again defining a function of the same name.
As follows:
function Bfun (num) { return num + $; } var cfun = Bfun; Bfun = function (num) { return num*1000; }; Console.log (bfun);//100000 Console.log (Cfun (200));//300
function expression defines a function that does not overwrite a function with the same name defined by the function declaration, the function is an object in JavaScript, the function name is a variable pointer to a function, and the function name is also a variable.
One rule in JavaScript is that a function declaration overrides the declaration of a variable with the same name as its function, but does not overwrite the assignment of a variable with the same name, regardless of the order in which they are defined. When you use a function expression to set an
Bfun function, Bfun is also a variable, except that its assigned value is an anonymous function, and the value of a variable can be any type (string, number, Boolean, null, undefined, a
function, a complex type of data (object), and so on).
Validation: A function declaration overrides the declaration of a variable with the same name as its function, but does not overwrite the assignment of a variable with the same name
Bfun = function (num) { return num*1000; }; var cfun = Bfun; function Bfun (num) { return num + $; } Console.log (bfun);//100000 Console.log (Cfun (200));//200000
Look at a piece of code, what's the final result?
Bfun = function (num) {
return num*1000; } ; var cfun = Bfun; Bfun = function (num) { return num + 200;
} Console.log (Bfun ()); Console.log (Cfun (200));
The final result is 300, 2000, the following Bfun covers the previous bfun, the second is called after calling Bfun, and Cfun is still the first Bfun value, why?
Not that the function is an object, the function name is equivalent to a pointer, the function is pointed to, after copying two variables will point to the same function?
When Bfun is defined in the form of a function declaration, the subsequent function declaration defines an identical function with the same name, Bfun changes, and cfun changes. The bfun here is a function defined by a function expression,
What difference does it make?
My understanding is that function expression defines a function that does not have a function name, copy is a specific value when copying, here is a copy of an anonymous function, instead of copying the same as the function declaration copy is a
memory address (pointer),
A copy of the function expression, which is equivalent to a copy of the basic data type variable, holds a copy of its own value between the variable and the variable, and the value change of one variable does not affect the other.
The memory allocation of a function (whether it is a function declaration or a function defined by a function expression):
A function expression differs from a function declaration in that Bfun is then re-assigned to an anonymous function, at which point Bfun points to a new object, which is somewhat similar to the literal way of defining properties and methods on a prototype.
A new object is pointed at this point, Cfun still points to the original anonymous function. That is, a function that defines a function, defines a function with the same name, a function with the same name overwrites the original function, and the function expression defines
function is not overwritten by a function with the same name, the original function is still present after defining the function with the same name.
A function is an object, so you can define properties and methods on the function name:
Bfun = function (num) { return num*1000; }; var cfun = Bfun; Bfun.a = 7777; Console.log (BFUN.A);//777 bfun.b = function (num) { return num + $;} Console.log (typeof Bfun);//function Console.log (BFUN.A);//777 Console.log (bfun);//10000 Console.log (bfun.b (100)); 300
Validation: Functions defined by function expressions are not overwritten by functions with the same name, and the original function is still present after the function with the same name is defined .
Bfun = function (num) { return num*1000; }; var cfun = Bfun; Bfun.a = 7777; Console.log (BFUN.A);//777 bfun = function (num) { return num + $; } Console.log (typeof Bfun);//function Console.log (BFUN.A);//undefined Console.log (bfun (100));//300 Console.log (cfun);//200000 Console.log (CFUN.A);//777
The function is an object, so you can add properties and methods on the function object, so that it seems that the object is not necessarily stored in heap memory? Anonymous functions in function expressions such function objects are present in the stack.
The function name is a pointer to a function, which is an object that exists in heap memory.
Four, closed package
var a = { b:function() { Console.log (this); }, f:function() { var c = this. b; c (); } }; A.B (); A.F ();
From the above analysis, C and B point to the same function, but why this point is different? The problem is the call (this is a when you call B directly, and after B is copied to C in F, the call C,this points to window)
Functions differently, and the resulting execution environment is different.
This example is essentially similar to (This===window):
var object = { _name: "My Object", getnamefunc:function () { var = this; var a = function () { Console.log ("Value:" +this._name);//undefined }; A (); }}; Console.log (Object.getnamefunc ());
Also similar to (This===window):
var object = { _name: "My Object", getnamefunc:function () { return function () {// This._name = "yyy";
console.log (this);//window return this._name;//undefined }; } ; Console.log (Object.getnamefunc ());
The above three examples all create a closure function in the function
Closure: A function that has access to a variable in another function is a closure, and a common closure is a function that contains another function
When the function is not invoked with an object, this points to the window, and the this in the enclosing box points to the window, which extends to the problem that this is pointing to.
V. The point of this issue (see: https://www.zhihu.com/question/19636194)
There are several ways to call a function and the current this direction problem:
Called directly from the function name (no matter where it is called), this point points to the window
Called by the name of the object point function, this pointer to the direct caller of the function
The new keyword invokes the constructor, which points to the new object
Called by the Apply or call method, this points to the object in the first argument, if the first argument is null,this points to the window
You can also change the scope of a function by using the bind () method, which returns an instance of a function that ultimately calls the function via this instance (the Apply and call methods are directly called functions)
The Apply and call methods are used to change the scope of a function, which is the two non-inherited methods contained in each function.
function A (num, num2) {}
When a function is called directly by a functional name, which is equivalent to a.apply (null, arguments), the first argument is null, so this points to the window
var b = { function A (num, num2) { }}
When calling a function through an object B.A, which is equivalent to a.apply (b, arguments), the first argument is B, so this is pointing to B
When you change the method of calling a function into the form of apply or call, it is good to understand the point of this
the difference between calling a function directly and calling the constructor through the new key is as follows:
To investigate the problem of the point and variable elevation of this in different invocation modes
var a=10;function test () {A=5;alert (a); alert (THIS.A); var a;alert (THIS.A); alert (a);} Test (); New test ();//5 5//5 undefined undefined 5
The test () method, this pointing to Window,test, defines a with Var, which is promoted to the forefront of the execution environment, a=5
New test (), when Test is a constructor, THIS.A is not defined as undefined
Summarize:
The actual scenario for the above problem is as follows:
Abstract part of the actual project, used to unify the syntax of adding events to DOM elements, greatly improving the maintainability of the Code
var util = {maps: {' Click #btn ': ' clickbtn '}, Stop:function () {console.log ("stop ..."); }, Clickbtn:function (event) {var e = Event;var target = E.target | | e.srcelement;console.log (target.id); This.stop (); }, _scaneventsmap:function (maps, isOn) {var delegateeventsplitter =/^ (\s+) \s* (. *) $/; var bind = IsOn? This._delegate.bind: This._undelegate.bind (this);//This._delegate (' click ', "#btn", this["clickbtn"]); /bind (' click ', "#btn", "clickbtn"); for (var keys in maps) {if (Maps.hasownproperty (keys)) {var matchs = key S.match (Delegateeventsplitter); Bind (Matchs[1], matchs[2], Maps[keys]); }}}, _delegate:function (name, selector, func) {var ele = Document.queryselect or (selector), that = this, Func = This[func]; Console.log (func); Ele.addeventlistener (name, function (event) {var e = event | | window.event; Func.apply (that, arguments); }, False); }, _undelegate:function (name, selector, func) {var ele = $ (selector); Ele.removeeventlistener (Name, func, false); }, _init:function () {This._scaneventsmap (this.maps, true); }} util._init ();
This, Apply/call, bind, closure, function, variable copy