this problem in function

In the statement of the function body, the word this will appear. This is the context of the function

Whoever this is in the function indicates who the context of the function is

Who is this in the function depends on how it is called, because this is not immutable

For example, look at the following case

<script>
      var obj = {
        a: 100,
        fun: function () {
          console.log(this.a);
        },
      };
    </script>

At this time, we define a fun function in the obj object, which is the obj attribute

Now, if the direct object is called

obj.fun()

100 will be output, indicating that the context is the object itself

If the entire method is assigned once

 <script>
      var obj = {
        a: 100,
        fun: function () {
          console.log(this.a);
        },
      };
      var f = obj.fun;
      f();
    </script>

undefined will be output in the page, because the context of this is not obj, but window

If an A is defined externally, the value 200 of the external a is output at this time

<script>
      var a = 200;
      var obj = {
        a: 100,
        fun: function () {
          console.log(this.a);
        },
      };
      var f = obj.fun;
      f();
    </script>

 

1. Execute directly with parentheses, and the context is a window object

Direct parenthesis calls are executed without object punctuation, not square bracket enumeration. They are usually executed separately after being extracted from arrays and objects

 <script>
      var a = 200;
      var obj = {
        a: 100,
        fun: function () {
          console.log(this.a);
        },
      };
      var f = obj.fun;
      f();
</script>

f() is executed directly with parentheses, because this f is extracted from obj

be careful:

  • this executed directly with parentheses points to the window object
  • Note that all global variables in js are attributes of window objects
  • It should also be noted that IIFE also belongs to the category of direct parenthesis call, and this in it is a window object

Let's look at IIFE

<script>
      var a = 200;
      var obj = {
        a: 100,
        fun: (function () {
          console.log(this.a);
        })()
      };
    </script>

At this time, the output is 200, and this of IIFE points to window

 

Sub topic 1:

   <script>
      var xiaoming = {
        name: "Xiao Ming",
        age: 25,
        sayHello: (function () {
          return this.age >= 18 ? "schoolboy" : "under age";
        })(),
      };
      console.log("Hello, my name is" + xiaoming.name + ",I am a" + xiaoming.sayHello);
    </script>

The answer is male. The key point of this question is this in IIFE. As we said above, this in IIFE points to window, so this in IIFE at this time Age is undefined. Because undefined > = 18, the result is false, and the ternary expression follows the "minor"

The output description this Age is less than 18

We output this Take a look

<script>
      var xiaoming = {
        name: "Xiao Ming",
        age: 25,
        sayHello: (function () {
          console.log(this.age)
        })(),
      };
      xiaoming.sayHello()
    </script>

 

Sub topic 2:

    <script>
      var obj = {
        a: 100,
        fun: function () {
          var a = 200;
          console.log(this.a);
        },
      };
      var a = 200;
      var f = obj.fun;
      f();
    </script>

 

The output is 200

Remember that who this points to must depend on the call. At this time, we find that the call is executed directly by parentheses. So we know that the internal this is the window, so all a in obj is a cover up. Because global variables are attributes of window objects,

So var a=200 is window A = 200, and the pop-up result is 200

 

2, the function that is called from the object or enumerated in the array, the context is this object or array.

The argument to the function is an arguments object

 <script>
      function fun(a, b, c, d, e, f) {
        console.log(arguments);
      }
      fun(1, 2, 3, 4, 5);
    </script>

Each function has an attribute of arguments and a value of a class array object

 

What is a class array object?

Class array objects are very similar to arrays. In essence, they are objects. They have the length attribute of the array and the corresponding subscript index value. arguments or document. Of the function Get * * when getting DOM, the returned object types are array like objects, because these objects look like arrays, but

It does not have the ability of array, and can not perform push and other operations

this is the context in the function. It depends on how to call it. If you want to express the function itself, use arguments callee

 <script>
      function fun() {
        console.log(arguments.callee == fun);
      }
      fun();
    </script>

 

Sub topic 3:

<script>
      function fun1(a, b, c) {
        arguments[0]();
      }

      function fun2(a, b, c, d, e) {
        consloe.log(this.length);
      }
      fun1(fun2, 1, 2, 3, 4, 5, 6);
    </script>

At this point, who this is depends on the call. When fun1 is called, when fun1 is called, the function executes arguments[0]. Because arguments is the argument list of fun1, item 0 is the fun2 function, so it complies with rule 2; This in the fun2 function refers to the function of fun1

The arguments class is an array object, so the length is 7

 

Sub topic 4:

At this point, we upgrade the above topic

 <script>
      function fun1(a, b, c) {
        arguments[0](1, 2, 3, 4, 5, 6);
      }
      function fun2(a, b, c, d, e) {
        console.log(this.length); 
        console.log(arguments.length); 
        console.log(arguments.callee.length); 
        console.log(this.callee.length);
      }
      fun1(fun2, 1, 2, 3, 4, 5, 6);
    </script>

 

Analysis: through analysis, we know that this in fun2 refers to fun1 function, so this Length refers to the arguments class array object of fun1 (because the class array enumeration complies with rule 2);

arguments itself is the argument list of fun2 function itself, so the length is 6 (1 ~ 6 parameters are passed when calling);

arguments.callee is the fun2 function itself, so length is the formal parameter list, which is 5;

this.callee.length means that the formal parameter list of fun1 is 3

 

Sub topic 5:

      var m = 2;
      var obj = {
        fun1: function () {
          return this.fun2();
        },
        fun2: fun2,
        m: 4,
      };

      function fun2() {
        return this.m;
      }
      console.log(obj.fun1());

 

Sub topic 6:

      var num = 1;
      var obj = {
        num: 2, 
        fun: (function () {
          var num = 3;
          this.num += 4;
          return function () {
            this.num *= 5;
            num *= 6; 
            console.log(num);
          };
        })(),
      };
      obj.fun(); 
      obj.fun(); 
      console.log(num); 
      console.log(obj.num); 
      var f1 = obj.fun;
      f1(); 
      console.log(num); 
      console.log(obj.num); 
      var f2 = obj.fun;
      f2(); 
      console.log(num);

 

Sub topic 7:

    var length = 1;
      var obj = {
        length: 10,
        b: [
          {
            length: 20,
            fun: function () {
              console.log(this.length);
            },
          },
        ],
      };
      var arr = [obj, obj.b, obj.b[0], obj.b[0].fun];
      arr[0].b[0].fun(); 
      arr[1][0].fun(); 
      arr[2].fun(); 
      arr[3](); 

 

 

3. The timer is called directly, and the context is the window object

 var a = 100;

      function fun() {
        console.log(this.a);
      }
      setInterval(fun, 1000);

It should be noted that there are differences between timer calls and timer function internal calls

The following code is the timer calling obj Fun function, so the caller is a timer

  var obj = {
        a: 300,
        fun: function () {
          console.log(this.a++);
        },
      };
      var a = 100;
      setInterval(obj.fun, 1000);

 

 

 

The following code is essentially obj calling a function, so the context is obj

   var obj = {
        a: 300,
        fun: function () {
          console.log(this.a++);
        },
      };
      var a = 100;
      setInterval(function () {
        obj.fun();
      }, 1000);

 

 

4. this in the DOM event refers to the DOM element that triggers the event

var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');
var box4 = document.getElementById('box4');

function changeColor() {
    this.style.backgroundColor = 'purple'
}
box1.onclick = changeColor;
box2.onclick = changeColor;
box3.onclick = changeColor;
box4.onclick = changeColor;

The clicked element turns purple

 

 

5. call() and apply() can set the context of the function

The function context mainly depends on who is calling, but we can set the function context through call() and apply().

The essence of call() and apply() is to specify the context while calling the function

For example, we have a changeSex function, which is used to modify the properties of sex.

At this time, there is a xiaohong object, and sex is female

At this time, we call the changeSex function to forcibly bind the context of the function to xiaohong

  function changeSex() {
        if (this.sex == "male") {
          this.sex = "female";
        } else {
          this.sex = "male";
        }
        console.log(this);
      }

      var xiaohong = {
        name: "Xiao Hong",
        sex: "female",
      };
      changeSex.call(xiaohong);
      console.log(xiaohong.sex);

 

 

The apply function has the same function

changeSex.apply(xiaohong)

 

It should be noted that the essence and core of call() and apply() are different: it is mainly the difference in syntax. Call accepts parameters and apply accepts arrays

 

The call method requires that all parameters be listed one by one after the context object

   function person(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        console.log(this)
      }
      var xiaoming = {
        name: "Xiao Ming",
        age: 3,
        sex: "male",
      };
      person.call(xiaoming, "Xiao Hong",5,"female");
         

 

 

At this point, we change to apply, which requires that all parameters must be normalized into an array

  function person(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        console.log(this)
      }
      var xiaoming = {
        name: "Xiao Ming",
        age: 3,
        sex: "male",
      };
      person.apply(xiaoming, ["Xiao Hong",15,"female"])

 

 

apply essentially requires only two parameters, and the second parameter is an array collection

Both methods are the same in the use results

Sub topic 8:

      function fun1() {
        fun2.apply(obj, arguments);
      }

      function fun2(a, b, c) {
        console.log(obj);
        console.log(a);
        console.log(b);
        console.log(c);
      }
      var obj = {
        name: "Xiao Ming",
        sex: "male",
      };
      fun1("Xiao Hong", "Xiao Gang", "Xiaolan");

 

 

At this time, you will find that the function of apply is to structure the array with the second parameter and turn it into a list of parameters. For example, the arguments we passed in is an array like object, but we deconstruct the A, b and c formal parameters accepted by the fun2 function, that is to say, we separate them into

Xiao Hong, Xiao Gang and Xiao Lan

Sub topic 9:

Using the Math method to find the maximum value of the array

Math.max.apply(null, [5432,123,5342,43,4,6,48,43,43,43,48,94,43,51,123,2])

 

Keywords: OOP

Added by treybraid on Wed, 05 Jan 2022 15:41:24 +0200