javaScript this points to the problem

Posted by kevinkhan on Thu, 23 Dec 2021 13:04:39 +0100

Portal

1, this

Introduction: the reason why JavaScript language has this design is related to the data structure in memory.

var obj = { foo:  5 };

The above code assigns an object to the variable obj. The JavaScript engine will first generate an object {foo: 5} in memory, and then assign the memory address of the object to the variable obj.

That is, the variable obj is an address. If you want to read obj Foo, the engine first gets the memory address from obj, then reads the original object from the address and returns its foo attribute.

2, Judge the direction of this

(1) this point inside the independent function is the global window object

var x = 1;
var foo = function () {
    console.log("Independent function==>", this)     // window
    console.log("Independent function==>", this.x)   // 1
}
 foo();

(2) The method this inside the object points to the current object

var x = 1;
var obj = {
     x: 2,               // Object properties
     foo: function () {    // Copy the address of the function to foo
        x = 4
     // this here points to obj
     console.log("Inside the object this==>, ", this.x)    // 2
     var a = function () {
          // Point to window
          console.log(this.x) // 4 (x = 4 in foo, X is the global x, so the global x is modified)
      }
      a()         // 1
     }
}
obj.foo()   // Object function, called object method, points to obj

(3) this inside the constructor points to the object created by the new operator

function Dog(name, color) {
    this.name = name;
    this.color = color;
 }
 Dog.prototype.say = function () {
     console.log("Dog Prototype method of constructor==>", this)
 }
var dog = new Dog("Wangcai", "yellow");
dog.say()

3, Change the direction of this inside the function

(1)apply

Introduction: the apply() method calls a function with a given this value and the parameters provided in the form of an array (or array like object).

Syntax:

func.apply(thisArg, [argsArray])
  • parameter

    • thisArg: this value used when func function runs.

    Note that this may not be the actual value seen by this method: if this function is in non strict mode, it will be automatically replaced with pointing to the global object when it is specified as null or undefined.

    • argsArray: an array or array like object in which the array elements will be passed to the func function as separate parameters. If the value of the parameter is null or undefined, it means that no parameters need to be passed in.
  • Return value specifies the return value after func function call after this value and parameter.

function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.apply(this, [name, price]);
  this.category = 'food';
}

console.log(new Food('cheese', 5).name);

(2)call

Description: the call() method uses a specified this value and one or more parameters given separately to call a function.

Note: the syntax and function of this method are similar to those of the apply() method, except that the call() method accepts a parameter list, while the apply() method accepts an array containing multiple parameters.

Syntax:

function.call(thisArg, arg1, arg2, ...)
  • parameter

    • thisArg is the value of this used when the function function runs.
    • arg1, arg2,... The specified parameter list.
  • Return value specifies the return value after func function call after this value and parameter.

  • example:

    function Product(name, price) {
      this.name = name;
      this.price = price;
    }
    
    function Food(name, price) {
      Product.call(this, name, price);
      this.category = 'food';
    }
    
    console.log(new Food('cheese', 5).name);
    

(3)bind

Introduction: the bind() method creates a new function. When bind() is called, this of the new function is specified as the first parameter of bind(), and the other parameters will be used as the parameters of the new function for calling.

grammar

function.bind(thisArg[, arg1[, arg2[, ...]]])
  • parameter

    • The value passed to the target function as the this parameter when thisArg calls the binding function. If you use the new operator to construct a binding function, the value is ignored. If thisArg is null or undefined, this of the execution scope will be regarded as thisArg of the new function.
    • arg1, arg2,... When the target function is called, it is preset into the parameter list of the binding function.
  • Return value returns a copy of the original function with the specified this value and initial parameters.

const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

const unboundGetX = module.getX;
console.log(unboundGetX()); // This function is called at the global scope
// undefined

const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// 42

4, Use apply, call and bind to implement some small cases

 // (1) Handle with apply or call
 // Find the largest value in the array
 var arr = [4, 1, 88, 56, 999, 12, 7, 1000];
 Array.prototype.findMax = function () {
       console.log(this) // Current this refers to the caller [4, 1, 88, 56, 999, 12, 7, 1000]
       /*
          a.apply(b, c) Call the a function, change this inside the a function to point to b, and pass in the c array as the parameter
       */
       return Math.max.apply(this, this) // The first this is the caller and the second this is the data
       // Where null is window
       return Math.max.apply(null, this)
       // Processing with call -- deconstructing ES6 writing method
       return Math.max.call(null, ...this)
}
console.log(arr.findMax())
var x = 10;
var modules = {
      x: 100,
      // getX is the property of the object
      getX: function () {
          console.log(this)
          return this.x
      }
 }
// 100. The context is in the object of modules
console.log("Direct call==>", modules.getX())
// 10 copy the function value to the external getX2. getX2 is in the most external context, so the internal this of the executed getX2 points to the window
var getX2 = modules.getX; 
console.log("External getX2 variable==>", getX2());
var getX3 = getX2.bind(modules) // Not implemented
console.log("External getX3 variable==>", getX3());

Welcome to my personal blog

Topics: Javascript