Brief talk on javascript bind method

Keywords: Javascript JQuery

Recently, I went to an interview and talked with the interviewer about many things based on JS. One of the questions is about the understanding and difference of apply, call and bind. Suddenly stunned, apply, call I know, often used things, what is the ghost of bind!!! Seems like I've seen and read similar articles, but... I don't remember... Is it the same as jQuery's event-bound bind...

Since I don't know, let's make a summary.~

 

apply and call

Now that I mentioned the two brothers, I also followed the simple knowledge. In javascript, the direction of this is a common problem to deal with. One of the more classical problems is that document.getElementById is too long, tired and annoying to knock. It's encapsulated in a short way. Here's how simple it is to do two lines of code.

<div id="test"></div>
<script>
    var getDom = document.getElementById;
    console.log(getDom("test"))
</script>

But... When invoked, the system prompted Uncaught TypeError: Illegal invocation ah... What a ghost error! In fact, this is the problem of this. With document.getElementById, this points to document when the function is executed, but with getDom, this points to window when the function is executed. And if getElementById uses this in the kernel implementation, so will report a mistake!!!

The correct encapsulation method is as follows: (i.e. using apply/call to set this point when a function is called)

<div id="test"></div>
<script>
var getDom = (function(func){
    return function(){
        return func.apply(document , arguments);
    }
})(document.getElementById);
console.log(getDom("test"))
</script>

Summary: Apply and call are used in the same way, that is, to change and determine the direction of this when the function is executed, the difference is that the latter parameter of apply is an array, and the latter parameter of call is a bunch of parameters. Don't say much, get to the point...

 

2. Basic of bind

First, let's talk about the difference between apply/call and apply/call. The bind method returns a function that will not be executed immediately, but will be executed only when () is called, while apply/call is an immediate function.

MDN explains that the bind() method creates a new function called a binding function. When the binding function is called, the binding function calls the original function in sequence with the first parameter of the bind() method passed in when it is created as this, the second parameter of the bind() method passed in and the subsequent parameters plus the parameters of the binding function itself when it runs.

Next, use demo simply

1. Simple binding this

var person1 = {
    name : "sky" ,
    getName : function(){
        return this.name;
    }
}
var person2 = {name : "moon"};
var getName = person1.getName.bind(person2);        //binding person2 Act as getName Function execution this
console.log(getName());            //Printed values are moon

This is easy to use.

 

2. Form of Passing Parameters

var self = {name : "sky" , age: 26}
var getDescription = function(country , city){
    console.log("my name is " + this.name + " , my age is " + this.age + " , I'am from " + country + " " + city);
}.bind(self , "China");
getDescription("WuHan");            //my name is sky , my age is 26 , I'am from China WuHan

Personally, this is equivalent to preset some parameters through the bind method, such as the preset count parameter at this time, when invoked, passing dynamic parameters, such as WuHan here. By binding this in this way, with the preset parameters, the degree of flexibility is very high.

 

3. Use scenarios of bind

Limited level, just talk about individuals. I like to use var_this = this in the code of nested multi-level functions; to save this in the scope of the superior function, so that in the embedded function, we can use _this to get this in the scope of the superior function. If you use bind, you can change the way. The specific comparison is as follows:

<div id="test1">test1</div>
<div id="test2">test2</div>
<script>
    //Old Writing, Use_this Preservation
    var tool1 = {
        name: "sky1",
        bindEvent: function() {
            var _this = this;
            document.getElementById("test1").addEventListener("click", function() {
                console.log(_this.name)
            }, false)
        }
    }
    //New Writing, Use bind binding
    var tool2 = {
        name: "sky2",
        bindEvent: function() {
            document.getElementById("test2").addEventListener("click", function() {
                console.log(this.name)
            }.bind(this), false)
        }
    }
    tool1.bindEvent();
    tool2.bindEvent();
</script>

How to say, the code looks more beautiful. I'm a Yan Value Controller.

 

IV. bind COMPATIBILITY

The bind method is an extension of ES5, so IE6, 7, 8 are incompatible... the whole person is not good.

What to do? There are a lot of compatible materials on the Internet. I prefer to make wheels by myself. In fact, it's quite simple. It's the encapsulation and use of apply/call. Learning, step by step, is divided into two steps. The skyBind method is used to express the following.

1. Implementing only the function of modifying the execution environment, that is, this

Function.prototype.skyBind = function(context){
    var func = this;        //That's it!!! this func That is to say, it needs to be executed and bound. context Function!!!!!!
    return function(){
        return func.apply(context , arguments);            //Bind and execute
    }
}
var person1 = {
    name : "sky" ,
    getName : function(){
        return this.name;
    }
}
var person2 = {name : "moon"};
var getName = person1.getName.skyBind(person2);      
console.log(getName());            //Printed values are moon    

Very simple, no!!!

 

2. Function of adding parameters

Function.prototype.skyBind = function(){
    var func = this  ,    //Or it!!! this func That is to say, it needs to be executed and bound. context Function!!!!!!
        context = [].shift.call(arguments) ,            //At this point, the incoming parameters do not simply have this Direction, or other parameters, according to the provisions of the first parameter is the execution environment, get it.
        args = [].slice.call(arguments);                //arguments Has the properties of arrays, after all JS It's a weak type of language.,But after all, it's not an array. In this way, it's an array. arguments Convert to an array, no need slice change into splice Or anything else.
    return function(){
        /* Bind and execute. The parameters of the execution function are the merge of two arrays.
         * What needs to be explained here is that args is the parameter passed in when bind binds, such as China in the demo below, while the arguments below are the parameter WuHan that is passed in when the actual call is made.
         * */
        return func.apply(context , [].concat(args , [].slice.call(arguments) ));            
    }
}
//demo
var self = {name : "sky" , age: 26}
var getDescription = function(country , city){
    console.log("my name is " + this.name + " , my age is " + this.age + " , I'am from " + country + " " + city);
}.skyBind(self , "China");
getDescription("WuHan");            //my name is sky , my age is 26 , I'am from China WuHan

  

Do it!!!

Posted by UnknownPlayer on Mon, 27 May 2019 13:04:49 -0700