JavaScript Advanced Programming-this

Preface

Originally, this should be put in "Context and Scope". When I found myself sorting out, there were more and more examples. So I wrote a single article to deepen my understanding. Some problems related to this can be further improved in my future work or project.

this

concept

What is the value of this in a function is determined when the function is actually called and executed, but not when the function is defined.

Because the value of this is part of the execution context environment, a new execution context environment is generated every time a function is called.

Constructor

A constructor is a function for a new object. In fact, strictly speaking, all functions can have a new object, but some functions are defined for a new object, while some functions are not. Also note that the first letter of the constructor's function name is capitalized (rule convention). For example: Object, Array, Function, etc.

function Foo() {
            this.name = "yzh";
            this.year = 1996;
            console.log(this); //Object { name: "yzh", year: 1998 }
        }
        var f1 = new Foo();
        console.log(f1.name); //yzh
        console.log(f1.year); //1996

In the above code, if the function is used as a constructor, then this represents the object it is about to come out of.

Note that the above case is limited to newFoo(), where the Foo function acts as a constructor. If you call the Foo function directly instead of the new Foo(), the situation is quite different.

function Foo() {
            this.name = "yzh";
            this.year = 1996;
            console.log(this); //Object { name: "yzh", year: 1998 }
        }
        Foo();  //window

In this case this is window.

Function as an attribute of an object

If a function is an attribute of an object and is called as an attribute of an object, this in the function points to that object.

var obj = {
            x: 10,
            fn: function() {
                console.log(this); //Object { x: 10, fn: fn() }
                console.log(this.x); //10
            }
        };
        obj.fn();

In the above code, fn is called not only as an attribute of an object, but also as an attribute of an object. As a result, this is an obj object.

What would happen if the fn function was not called as an attribute of obj?

var obj = {
            x: 10,
            fn: function() {
                console.log(this); //window
                console.log(this.x); //undefined
            }
        };
        var f1 = obj.fn;
        f1();

As shown in the above code, if the fn function is assigned to another variable and not called as an attribute of obj, then the value of this is window, and this.x is undefined.

Functions are called with call or apply

In order to prevent you from not understanding this basic and important thing first

Internal attributes of functions

Inside the function, there are two special objects: arguments and this.
This article mainly introduces arguments, which is a class array object, including all the parameters of the incoming function. This object also has an attribute called callee, which is a pointer to the function that owns the arguments object.

This example is mainly used to eliminate the close coupling between the execution of functions and functions of the same name. The code is as follows:

function factorial(num) {
            if (num <= 1) {
                return 1;
            } else {
               // return num * factorial(num - 1);
                //1. Application of General Recursive Algorithms
                return num * arguments.callee(num - 1) 
                //2. Better practices
            }
        }

        var trueFactorial = factorial;

        factorial = function() {
            return 0;
        };

        alert(trueFactorial(5)); //120
        alert(factorial(5)); //0

Functional attributes

Each function contains two attributes: length and prototype.
length denotes the number of named parameters the function wishes to accept

function sayName(name){
            alert(name);
        }      
        
        function sum(num1, num2){
            return num1 + num2;
        }
        
        function sayHi(){
            alert("hi");
        }
        
        alert(sayName.length);  //1
        alert(sum.length);      //2
        alert(sayHi.length);    //0

The prototype attribute is not repeated here.

Functional method

Each function contains two non-inherited methods: apply() and call(), both of which are used to call functions in specific scopes, which are actually equivalent to setting the value of this object in the function body.

The apply() method takes two parameters: one is the scope in which the function is run, and the other is an array of parameters.

function sum(num1, num2){
            return num1 + num2;
        }
        
        function callSum1(num1, num2){
            return sum.apply(this, arguments);
        }
        
        function callSum2(num1, num2){
            return sum.apply(this, [num1, num2]);
        }
        
        alert(callSum1(10,10));   //20
        alert(callSum2(10,10));   //20

callsSum1() executes the sum() function by passing this as the value of this (called in global scope, so the incoming object is a window object), the following example is the same.

The call() method is similar to the apply() method in that it accepts parameters differently. Simply put, the parameters passed to the function must be listed one by one. (If it's a parametric function, you don't need to pass parameters)

function sum(num1, num2){
            return num1 + num2;
        }
        
        function callSum(num1, num2){
            return sum.call(this, num1, num2);
        }
        
        alert(callSum(10,10));   //20

Transfer parameters are not the real use of two functions, but the real power is to expand the scope on which the function operates.

window.color = "red";
        var o = { color: "blue" };
        
        function sayColor(){
            alert(this.color);
        }
        
        sayColor();            //red
        
        sayColor.call(this);   //red
        sayColor.call(window); //red
        sayColor.call(o);      //blue

The following code is implemented without the use of functions.

window.color = "red";
        var o = { color: "blue" };
        
        function sayColor(){
            alert(this.color);
        }
        
        sayColor();     //red
        
        o.sayColor = sayColor;
        o.sayColor();   //blue

If you want to output the color attribute value in the o object, you must assign the sayColor function to the object o and call o.sayColor(), and this refers to the object o.

Return to examples

When a function is called by call and apply, the value of this takes the value of the incoming object.

var obj = {
            x: 10
        };
        var fn = function() {
            console.log(this); //Object { x: 10 }
            console.log(this.x); //10
        };
        fn.call(obj);

Global & Calling Common Functions

In the global environment, this will always be window, which should not be criticized.

console.log(this === window); //true

When ordinary functions are called, this is also window.

var x = 10;
        var fn = function() {
            console.log(this); //window
            console.log(this.x); //10
        }
        fn();

Note the following

var obj = {
            x: 10,
            fn: function() {
                function f() {
                    console.log(this); //Window 
                    console.log(this.x); //undefined
                }
                f();
            }
        };
        obj.fn();

Although function f is defined in obj.fn, it is still a normal function, and this still points to window.

Summary: this points to the object calling the function

What does this represent in the prototype of the constructor

function Fn() {
            this.name = "yzh";
            this.year = 1996;
        }
        Fn.prototype.getName = function() {
            console.log(this.name);
        }
        var f1 = new Fn();
        f1.getName(); //yzh

In the Fn.prototype.getName function, this points to the F1 object. So you can get the value of f1.name through this.name

End

Welcome to pat bricks, there are more good examples, welcome to put forward, the article is also welcome to correct errors.

Keywords: Javascript Attribute

Added by cosmicsea on Sat, 29 Jun 2019 23:15:30 +0300