This, Apply/call, bind, closure, function, variable copy

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.