js this points to the problem - this in the context of function execution

this in the context of function execution

As we know from the above, the general calling method is to call the method on the window.

How to get this of the current function?

1 change this through call/bind/apply

this.myName = 'jszhang';
let foo = function() {
  this.myName = 'zhangsan';
}
foo();
console.log(window.myName); // Output what?
console.log(foo.myName); // Output what?

At this time, this points to window, so the output result is;

zhangsan

undefined

After binding through call:

this.myName = 'jszhang';let foo = function() {
  this.myName = 'zhazhazhang';}foo.call(foo);console.log(window.myName);
   // Output what?
console.log(foo.myName); // Output what?

The output result is:

jszhang

zhazhazhang

Of course, you can also change to apply and bind. There is no exhaustive description here.

2 call method settings through objects
Use an object to call a method inside it. this of the method points to the object itself.

Case 1

let myObj = {
  name: 'jszhang',
  showThis: function() {
    console.log(this.name);
  },};myObj.showThis(); // Output what?

Answer: output jszhang.

We should always remember: who calls points to who. Here is a call through myObj, so this at the moment points to myObj. There is name: jszhang in myObj, so jszhang is output.

Of course, we should know ourselves clearly:

Case 2

let myObj = {
  myName: 'jszhang',
  showThis: function() {
    console.log(this.myName);
  },};
let foo = myObj.showThis;foo(); // Output what?

At this time, it becomes window pointing again. Now let foo = myobj Showthis is just a definition. The real implementation is in foo(). So what's the matter with foo() now? window. Foo! There is no doubt that the output is undefined.

Case 3

let myObj = {
  name: 'jszhang',
  showThis: function() {
    console.log(this.name);
  },}
let foo = myObj.showThis;foo(); // Output what?

Generally speaking, the output of this code should be undefined.

However, it should be noted here that window Name is the name of the current window. It is window Open () opens a new web page. The value of the second parameter of this method.

So the output here is window Name is a null value '', or the name of the currently existing window.

jszhang takes his friends through an example to see how this comes from:

index.html

<!DOCTYPE html><html><head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>jszhang</title></head><body>
  <button>Open a new page</button>
 
  <script>
    (function() {
      const btn = document.querySelector('.btn');
      btn.onclick = function() {
        window.open('index.html', 'jszhang Web page');
      }
    })()
  </script></body></html>

In the console of the newly opened web page, enter window Name, get jszhang's web page.

Conclusion:

Call a function in the global environment. The this in the function refers to the global variable window.

An internal method is called through an object, and this in the execution context of the method points to the object itself.

3 set in the constructor

this.name = 'jszhang';let Foo = function() {
  this.name = 'zhazhazhang';}let foo = new Foo();console.log
  (foo.name);// Output what?
  console.log(window.name); // Output what?

The answer is:

zhazhazhang

jszhang

Before explaining the reason for this answer, let's take a look at what the JavaScript engine does in new Foo():

First create an empty object tempObj = {}.

Then call Foo The apply method takes tempObj as the parameter of the apply method, so that when the execution context of Foo is created, its this points to the tempObj object.

Then execute the Foo function. this in the execution context of the Foo function points to the tempObj object.

Finally, the tempObj object is returned.

function myNew(func, ...args) {
  const tempObj = {};
  func.apply(tempObj, args);
  return tempObj;}
this.name = 'jszhang';let Foo = function(name, age) {
  this.name = name;
  this.age = age;}let foo = myNew(Foo, 'zhazhazhang', 25);console.log
  (foo.name);  // Output what?
  console.log(foo.age); // Output what?
  console.log(window.name); // Output what?

As mentioned above, we can see that this belongs to tempObj and is bound to foo, so we get:

zhazhazhang

25

jszhang

Of course, after knowing this, we'd better improve the handwriting method of new, so as not to mislead our partners into thinking that new has done so much:

function myNew(func, ...args) {
  // 1. Judgment method body
  if (typeof func !== 'function') {
    throw 'The first argument must be a method body';
  }

  // 2. Create a new object
  const obj = {};

  // 3. Of this object__ proto__  Point to the prototype object of func class
  // That is, the instance can access the properties on the prototype chain where the constructor prototype (constructor.prototype) is located
  obj.__proto__ = Object.create(func.prototype);

  // In order to be compatible with IE, step 2 and step 3 can be combined
  // const obj = Object.create(func.prototype);

  // 4. Bind this through apply to execute and get the results after running
  let result = func.apply(obj, args);

  // 5. If the result returned by the constructor is a reference data type, the result after running will be returned
  // Otherwise, create a new obj
  const isObject = typeof result === 'object' && result !== null;
  const isFunction = typeof result === 'function';
  return isObject || isFunction ? result : obj;}
// Test function Person(name){
  this.name = name;
  return function() { // Used to test point 5
    console.log('Return reference data type');
  };}// Used to test points 2 and 3 person prototype. sayName = function() {
  console.log(`My name is ${this.name}`);}const me = myNew(Person, 'jszhang'); // Used to test point 4 me sayName(); //  My name is jszhangconsole. log(me); //  Person {name: 'jszhang'}
// Used to test point 1 / / const you = mynew ({Name: 'jszhang'}, 'jszhang'); 
// Error: the first parameter must be the method body

In this way, we know what new is in the constructor.

key word: Front end training

Keywords: this

Added by redmonkey on Wed, 23 Feb 2022 06:07:43 +0200