This, Call, and apply





QQ picture 20170103163230 JPG

2.1 this

  • All JavaScript functions have one inside the scopethisObject, which represents the object on which the function is called. The value is dynamically bound by the execution environment of the function. (Simply understood as, who calls to whom)
    2.1.1 The direction of this
  • removewithandeval, the direction of this can be roughly divided into the following four situations:
    • Functions are called as methods of objects;
    • Functions are called as normal functions;
    • The function is called as a constructor;
    • Function.prototype.callorFunction.prototype.applyIs called;
  • When a function is called as a method of an object,thisPoint to that object
    var object = {
      str : "object str".print : function(){
          return this.str; }};console.log(object.print());Copy the code
  • When called as a normal function,thisPoints to a global object. If you’re in a browser environment, this global object iswindowObject.
    var str = "global";    // global variable STR
    var object = {
      // Object attribute STR
      str : "object str".print : function(){
          return this.str; }};// Assign object methods to global functions
    var fn = object.print;
    console.log(fn());Copy the code
  • Web front-end, we’re familiar withcallback()Function, which is often called as a normal function, causesthisPoints to a tampered problem
    
             
    <html>
      <head>
          <meta charset="UTF-8">
          <title></title>
      </head>
      <body>
          <! -- DOM node ID attribute -->
          <input id="btn_id" type="button" value="click" />
          <script type="text/javascript">
              / / the global id
              var id = "global_id";
              document.getElementById('btn_id').onclick = function(){
                  // execute as an object, in which case this points to the DOM object and prints "div_id"
                  console.log(this.id);
                  // Declare a callback function
                  var callback = function(){
                      console.log(this.id);
                  }
                  / / dosomething after
                  // Since it is executed as a normal function, output "global_id"
                  callback();
              };
          </script>
      </body>
    </html>Copy the code
  • In the previous chapter we learned what a constructor (or constructor) is, except that it starts with a capital letter, starting withnewKeyword to call. A constructor, as its name implies, builds a new object, so it always returns an object after execution. So, when a function is called as a constructor,thisIt points to the object that was returned.
    var Person = function(){
      this.str = "person str";
    };
    var person1 = new Person();
    console.log(person1.str);    // Print "person STR"Copy the code
  • But it is worth noting if the constructor is explicitreturnAn object, thatthisIt is this object that points to, not the local variable of the constructor’s executing code block.
    var Person = function(){
      this.str = "person str";
      return {
          this.str = "new person str"; }};var person1 = new Person();
    console.log(person1.str);    // Print "new person STR"Copy the code
  • If throughFunction.prototype.callorFunction.prototype.applyBy calling a function, you can customize itthisPointing to.
    var str = "global";    // global variable STR
    var object1 = {
      str : "object1 str".print : function(){
          return this.str; }}; var object2 = {str : "object2 str"
    };
    console.log(object1.print());    // print "object1 STR"
    // Execute the object1.print() method via object2. So this refers to object2, and it says "object2str"
    console.log(object1.print.call(object2));Copy the code
2.1.2 The loss of this
  • Document.getelementbyid () is a native JS method that everyone is familiar with, but the method name is too long. I want to see if it works by replacing it with a function with a short name.

    
             
    <html>
      <head>
          <meta charset="UTF-8">
          <title></title>
      </head>
      <body>
          <! -- DOM node ID attribute -->
          <input id="btn_id" type="button" value="click" />
          <script type="text/javascript">/* * Example problem */ // assign getElementById to the getId method var getId = doc'ument. GetElementById; getId("btn_id"); '// Console error "Uncaught TypeError: This is because the getElementById() method uses this internally. This is the default way to point to a ducument object. // This refers to the window object. Var getId = function(id){return document.getelementById (id); }; getId('btn_id');</script>
      </body>
    </html>Copy the code

2.2 Call, apply, and bind

  • ECMAScript3 toFunctionThe stereotype definesFunction.prototype.callorFunction.prototype.applyBoth methods, whether functional style coding, or JavaScript design patterns, are widely used and practicedcall()andapply()Methods are also an important step towards being truly called a JavaScript programmer.
2.2.1 call
  • call()The method is passed inThe specifiedthisvalueparameterExecute a function.
    // Global variables
    var name = "window";
    // Public execution function
    function print(label){
      console.log(label + ":" + this.name);
    }
    / / object 1
    var person1 = {
      name : "Grubby"
    };
    2 / / object
    var person2 = {
      name : "Moon"
    };print.call(this,"global");    Global: / / output "window"
    print.call(person1,"person1");    / / output person1: Grubby. ""
    print.call(person2,"person2");    / / output "person2: Moon."Copy the code
2.2.2 the apply
  • apply()And the way they workcall()Exactly the same, the only difference is that the parameters that need to be passed into the function,apply()Is through theargumentsAn array-like object is passed as a parameter.
    print.apply(this,["global"]); / / output"global:window"
    print.apply(person1,["person1"]); / / output"person1:Grubby"
    print.apply(person2,["person2"/ / output])"person2:Moon"// The difference between the two/* fn.call(obj, arg1, arg2, arg3...) ; fn.apply(obj, [arg1, arg2, arg3...] ); * /Copy the code
  • When executing functions, JavaScript parsers don’t actually count the number, type, and order of parameters and arguments (which leads to JavaScript not having Java method overrides). JavaScript parameters are internally oneargumentsObject to represent. After comparison, it can be found that in factcall()Is the packagingapply()Syntax sugar, do not deliberately pass in an array, no matter how many parameters, just append after it.
  • call()andapply()Same thing if you pass inthisThe value isnull, will point to the default host object if pointed to in the browserwindow.
2.2.3 the bind
  • bind()ECMAScript5 is a new method, and compared to the first two methods,call()andapply()Is to change thethisAnd then execute the function, whilebind()Is to change thethisValue, returns the function.
    // As expected, output "person1:Grubby"
    var printForPerson1 = print.bind(person1);
    printForPerson1("person1");
    // Output "person2:Moon", both binding and execution parameters can be passed
    var printForPerson2 = print.bind(person2,"person2");
    printForPerson2();
    // This in printForPerson1() is bound, even if executed as person2.print(), still outputs the name of person1
    person2.print = printForPerson1;
    person2.print("person2");Copy the code
Then use
  • By borrowing methods from other objects, the effect is similar to inheritance

    // The Person constructor, which can specify a name
    var Person = function(name){
      this.name = name;
    };
    // the Student constructor
    var Student = function(){
      Person.apply(this.arguments);    // Borrow the constructor of Person
    };
    // Add a way for students to say their name
    Student.prototype.sayName = function(){
      return this.name;
    };
    // instantiate a William student
    var student1 = new Student("William");
    // The student does not have a name attribute, but eventually outputs "William"
    console.log(student1.sayName());Copy the code
  • Find the maximum or minimum value of an array using Call and apply

    var arr = [45.88.634.22.436.879];
    var maxNum = Math.max.apply(Math, arr);
    console.log(maxNum);
    var minNum = Math.min.call(Math,45.88.634.22.436.879);
    console.log(minNum);Copy the code
  • Merge arrays using Call and apply

    var arr1 = [1.2.3];
    var arr2 = [4.5.6];
    [].push.apply(arr1, arr2);
    console.log(arr1);
    // Output: [1, 2, 3, 4, 5, 6]Copy the code