What this in the end is?

this is the object properties and methods of the "current" (runtime) is located. this binding occurs in a function call, the value depends only on the position of the call (function except arrow).

When the function call will produce an execution context, this is a record of the execution context.

❌ errors Note:

this function itself is not the point; this has nothing to do and function scope; this position and statements unrelated, only the location and call a relationship.

 

Rank explain:

Call stack: reach all the functions currently executing position call.

 

Since this is bound object when you call, we just need to figure out this binding rules:

1. default binding

When the function is called, if the function is called directly, without any modification (without any objects before the function), then the default binding to this window.

If you are using strict mode, the default binding to undefined.

So, immediately execute the function at any location, inside a function this, always point window (strict mode undefined) .

    <Script> 
         // in the function declaration of a function scope 
        function A () {
             ! function B () { // front function symbols can be any function declaration expression becomes 
                the console.log ( the this ); // window 
            } ();
             ! function C () { // front function can have any symbolic expression becomes a function declaration 
                'use strict' ; 
                the console.log ( the this ); // undefined 
            } (); 
        } 
        var obj = {A } 
        obj.a ();
     </ Script>

2. implicit binding (implicit loss)

When the function is called, when the foregoing context object, this implicit binding rules bound to the object.

If nested, bound to the nearest context object (obj1.obj2).

    <Script>
         var obj2 = {A: 30 , foo: foo};
         var OBJ1 = {A: 20 is, obj2}; // Note obj2 first statement, otherwise an error 
        function foo () { 
            the console.log ( the this II.A) ; // 30 
            // the this === obj2 
        } 
        obj1.obj2.foo ();
     </ Script>

js listener callback function to bind a callback function to call DOM object.

    <div ID = "the root"> the Click the ME </ div> 
    <Script> 
        const the rootElement = document.querySelector ( 'the root #' ); 
        rootElement.addEventListener ( 'the Click', function () { // here function is prohibited to use the arrow 
            the console.log ( the this ); // the rootElement 
        })
     </ Script>

Front-end development in this most error-prone areas, is the problem caused by this point window (strict mode undefined) of the implicit binding is lost.

Implicit binding missing several common situations:

1. assigned to the variable

    <Script>
         var objA = { 
            A: 100 , 
            foo: function () { 
                the console.log ( the this II.A); 
            } 
        }; 
        objA.foo (); // 100 === objA the this 
        var FUNC = objA.foo; // equivalent = function FUNC () {} 
        // function call, the function corresponding to a direct call, without any modification, the default binding 
        FUNC (); // undefined === the this window 
    </ Script>

2. As a custom function parameters transmitted callback

The function of the context object as a parameter callback function, which is equivalent to the parameter variable assignment.

    <Script>
         var A = 'Outer' ;
         function foo () { 
            the console.log ( the this II.A); 
        } 
        var obj = {A: 'Inner' , foo}
         function doFoo (Fn) { // called when equivalent obj.foo = Fn 
            Fn (); // call position, equivalent to calling foo () 
        } 
        doFoo (obj.foo);   // 'Outer' === the this window 
    </ Script>

This problem can explain why React class components in the event callback function must be bound to trigger this:

First: React component class, a constructor, instance methods, static methods are run in strict mode.

React from Import 'REACT' ; 
Import ReactDOM from 'DOM-REACT' ; 

class {React.Component the extends the App 
    constructor (The props) { 
        Super (The props); 
    } 
    the onClick () { 
        the console.log ( the this ); // undefine 
    }
     / / behind with onClick callback function equivalent = this.onClick the callback; 
    // <Button onClick = {} the callback> the Click Me </ Button> 
    // called when the direct call the callback (), so this should be the default binding 
    // by the method as in the example, the model is strictly, it is undefined 
    // To use this method in the onClick, this needs to be explicitly bound 
    the render () {
         return (
            <button onClick={this.onClick}>Click Me</button>
        )
    }
 }

ReactDOM.render(<App />, document.getElementById('root'));

3. As a javascript callbacks built-in functions of the mass participation

Common are setTimeout, traversing the array of functions such as forEach, map, reduce, etc.

    <Script>
         function foo () { 
            the setTimeout ( function () { 
                the console.log ( the this ); // window 
            }, 1000 ); 
            the console.log ( the this ); // objA 
        }
         var objA = {} foo; 
        objA.foo (); 
        / * 
           The above method is setTimeout call timer, and two arguments, the first is a callback 
           function setTimeout (the callback, Delay) { 
               // wait DelayMS; 
               the callback (); 
           } 
        * / 
    </ Script>
    <Script>
         var ARR = [1,2,3,4,5,6 ]; 
        arr.forEach ( function (Item) { 
            the console.log ( the this ); // window 
        }); // equivalent direct execution method forEach 
        / * 
            the above method is equivalent to calling the forEach Array prototype chain incoming callback parameter 
            Array.prototype.forEach = function (the callback) { 
                the callback (); 
            } 
        * / 
    </ Script>

The above three cases are implicit binding is lost, resulting in this case using the default binding. In another case this function is modified callback.

PS: this binding implicit modification

This is usually some js library processor in the event callback function bound to the DOM element.

Such as: jquery library event callback function

<body>
    <div id="root">Click Me 1</div>
    <script>
        $("#root").click(function() { // click方法的回调函数
            console.log(this); // $("#root")
        })
    </script>
</body>

3. explicit binding

 js provides three methods show binding apply, call, bind. Other

There are three ways to invoke difference, can refer to specific details of the three methods .

By these three methods, this function can be bound to an unrelated objects, can also solve the implicit binding implicit loss problem.

1. Specify Objects

    <Script>
         function foo (STH) { // STH. 3 === 
            return  the this II.A STH +; // this.a === 2 
        }
         var obj = {A: 2 };
         var bar = function () {
             / / Apply call and immediately executed after binding, so use of the outer jacket layer functions 
            return foo.apply (obj, arguments);
             // if call 
            // return foo.call (obj, ... arguments) 
        };
         var B = bar (. 3 ); 
        the console.log (B); // . 5 
        // also through the bind 
        // var bar = foo.bind(obj, 3);
    </script>

2. To resolve this callback function is lost

1) to manually bind

The most typical are React class components in the event handler callback function, you need to bind this internal function bound to the current component.

. A this form of binding class assembly React event handler callback function in three ways:

  • Use the arrow points to this fixed function

This function has no internal arrow, so this function arrow outer code block this binding. Where the object that is defined.

This is normal and this is where the different objects during execution.

// Method arrows applied to this fixed function setTimeout, the class instance method 
class the extends the App React.Component { 
    constructor (The props) { 
        Super (The props); 
    } the Add
     = () => { 
        the console.log ( this ); // current assembly 
     the setTimeout ( () => { 
       the console.log ( the this ); // this assembly 
     }, 1000) 
    } 
    the render () { 
        return (
             <div the onClick = { the this .add}> the Click Me </ div>
         ) 
    } 
 }
  • Using the bind method bind in the constructor is not recommended binding in the callback function, because each time it generates a new function
class App extends React.Component{
    constructor(props) {
        super(props);
        this.add = this.add.bind(this);
    }
    add(e) {
        console.log(this); // 当前组件
        setTimeout(function(){
            console.log(this); // 当前组件
        }.bind(this), 1000)
    }
    render() {
        return (
            <div onClick={this.add}>Click Me</div>
        )
    }
 }
  • Use the arrows to function in the callback function of the event properties
class App extends React.Component{
    constructor(props) {
        super(props);
    }
    add(e) {
        console.log(this); // 当前组件
    }
    render() {
        return (
            <div onClick={(e) => this.add(e)}>Click Me</div>
        )
    }
 }

b. for the case forEach, setTimeout callback function such as implicit binding missing, in addition to the above functions and bind arrow arrow method, as well as

  • assigned to this variable parameter passing; for setTimeout, forEach like
class App extends React.Component{
    constructor(props) {
        super(props);
        this.add = this.add.bind(this);
    }
    add(e) {
        console.log(this); // 当前组件
        const that = this;
        setTimeout(function(){
            console.log(that); // 当前组件
        }, 1000)
    }
    render() {
        return (
            <div onClick={this.add}>Click Me</div>
        )
    }
 }
  • Using the parameters supplied function itself: forEach only applicable to other array method, does not apply to setTimeout.
class App extends React.Component{
    constructor(props) {
        super(props);
        this.add = this.add.bind(this);
    }
    add(e) {
        console.log(this); // 当前组件
        const that = this;
        ([1]).forEach(function(item) {
            console.log(this); // 当前组件
        },that);// 传入参数
    }
    render() {
        return (
            <div onClick={this.add}>Click Me</div>
        )
    }
 }

4. new bindings

Use of a new instance of the command when the constructor function, logic is as follows:

1) Create an empty object

2) the object points to the prototype object constructor prototype property

3) this empty object is bound to this

4) in other cases returns no objects, return this

5. Priority

new bindings> Show Binding> implicit binding> default binding

 

       

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/lyraLee/p/11609709.html