First, the nature of functions

The essence of a function is an object, and a function name is a pointer to a function object. Based on this, the function has the following characteristics.

1. There is no overloading of a function. Declaring a function with the same name just overwrites the value of the function.

2. A function can be passed as a value to another function, and one function can be returned as the result of another function.

Second, function call method

After a function is defined, it is executed when it is called. There are four ways to call a function

1. As a function

2. As a method

3. As a constructor

4. Call through the function’s call() and apply() methods

3. The direction of this

This is the internal property of the function, and this refers to the calling context of the function. Depending on how the function is called, this points to something different.

1. Being called as a function (important)

In non-strict mode, this specifies window(global object); in strict mode, this refers to undefined.

In the React framework event binding, the callback function is called as a function instead of an instance, and strict mode is turned on. By default, this in the callback function is undefined.

Furthermore, whether a function is passed as a value as an argument to another function, returned as the result of another function, or called nested within a function (or method), this can be considered to refer to a global object, as shown below.

var obj={ m:function(){ console.log('m',this); f() function f(){ console.log('f',this); ƒ} Window {0: global, Window: Window, self: Window, document: document, name: ", "location, location,... }Copy the code

In order for an inline function to access an object, we must save this in the same scope as the inline function, for example:

var obj={ m:function(){ console.log('m',this); var self=this; f() function f(){ console.log('f',self); }}}Copy the code

2. As a method

Method calls are typically defined in the object definition, and the object instance calls the method, in the form of o.m(). So the call context (to which this points) is the object instance.

3. Called as a constructor

When the function is called as a constructor, this points to the newly created object.

function Person(name,age){
	this.name=name;
	this.age=age;
}
var p1=new Person("Alice",20)
Copy the code

The object creation code above goes through four steps:

Create a new object

(2) Make the new object call the constructor, assigning the constructor’s calling context to the new object (thus this refers to the new object).

(3) Execute the code in the constructor (add attributes to this new object)

(4) Return a new object

3. Call through the function’s call() and apply() methods

(1) the Function. The prototype. The apply ()

The apply() method specifies this to be used when the function is run, and provides arguments as an array.

(2) the Function. The prototype. The call ()

The call() method specifies the this used by the function at run time, with one or more arguments given separately as function arguments.

Both methods have the same effect, displaying the value of this when the specified function is called. The power is to extend the scope in which the function runs, so that the object does not need to have any coupling with the method. Any function can be called as a method of any object, even if the function is not a method of that object.

var color="yellow"; Var sayColor ={color:"blue"} sayColor(); / / output blueCopy the code

In addition to this, there is the function.prototype.bind () method, which creates a new Function. When bind() is called, this of the new Function is specified as the first argument to bind(), and the remaining arguments will be used as arguments to the new Function. Methods like apply and call change this work all at once, while bind can change it all at once and return a new function.

var color="yellow"; Var obj={color:"blue"} let sayColor1= saycolor.bind (obj) sayColor1(Copy the code

The arrow function this points to

The arrow function does not have an internal property called this, so the arrow function is called along the scope chain looking for this, that is, until it finds this of the outer function.

Developer.mozilla.org/zh-CN/docs/…

var id=21 function foo(){ var id=12; console.log("foo ",this.id); SetTimeout (()=>{console.log("setTimeout ",this.id)})} foo() Output: foo 21 setTimeout 21Copy the code

In the code above, the scope chain of the timer’s arrow function execution environment is arrow function ->setTimout->foo-> global. So the arrow function’s this finds the setTimeout function’s variable object along the scope chain, and this points to the window. So the output id value is 21. Such as:

Var obj = {I: 10, b: () => console.log(this), c: function() {console.log(this)}} obj.b() outputs the Window global objectCopy the code

In the above code, the scope chain of the execution environment of the arrow function is arrow function -> global, so the output is Window.

In the following code, a class is defined using a class in which methods can use arrow functions

class Animal { constructor(type) { this.type = type } walk() { console.log( 'walk ',this ) } say=()=>{ Console. log('say',this)}} let a=new Animal("cat") a.walk() ƒ} a.sun () Animal {type: "cat", say: ƒ} var walk = a.sun () this is undedined var say1= a.sun; Say1 () outputs this is an instance object Animal {type: "cat", say: ƒ}Copy the code

Methods in the class have strict mode turned on by default, and this refers to undefined in strict mode.

The walk() method is defined by non-arrow functions, and the say() method is defined by arrow functions.

Walk1 () is called in the global execution environment and is called as a normal function. Walk1 () is called in the global execution environment and is called as a normal function. Walk1 () refers to the global object.

2. But the arrow function this points to is confusing. Why do a.say() and say1() output this to instance objects? This is widely used as a shorthand for react component instances.

Looking at the instance object of A, the output is as follows, with the non-arrow function walk() defined on the prototype and the arrow function say() defined on the instance property of the object.

Manufacturer: ƒ} Animal {type: "cat", say: ƒ} ƒ Walk () [[Prototype]]: ObjectCopy the code

I don’t know what the t-arrow function means when class defines a class. Let’s assume that when class defines a class, instance methods are defined as arrow functions, and this always points to the object at which it was defined. For other scenarios, follow the instructions on MDN that arrow function this points to. The arrow function does not have this and looks for this along the action chain.