In-depth understanding of the Function.prototype.bind() method in JS

foreword

Function binding is probably the least of your attention when using JavaScript, but when you realize you need a solution to how to keep this context in another function, what you really need is Actually Function.prototype.bind() , it's just that you may still not realize it.

The first time you encounter this problem, you may be inclined to set this to a variable so that you can continue to refer to it after changing the context.

1. Syntax of bind

bind()The main function of the method is to bind the function to an object, the bind() method will create a function, and the value of the this object in the function body will be bound to bind()the value of the incoming function.

1.1 Definitions

bind() is defined as follows:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

The bind() function creates a new function (called the bind function) with the same body as the called function (the target function of the bind function). When the target function is called the this value is bound to bind()the first parameter of , which cannot be overridden.

1.2 Principle

bind()The principle can be simulated with the following code :

?
1
2
3
4
5
6
Function.prototype.bind = function (context) {
  var self = this ; // 保存原函数
  return function () { // 返回一个新函数
   return self.apply(context, arguments); // 执行新函数时,将传入的上下文context作为新函数的this
  }
}

1.3 Syntax

?
1
Function.prototype.bind(thisArg[, arg1[, arg2[, ...]]])

2. Application scenarios of bind

2.1 Implementing Object Inheritance

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var A = function (name) {
  this .name = name;
}
  
var B = function () {
  A.bind( this , arguments);
}
  
B.prototype.getName = function () {
  return this .name;
}
  
var b = new B( "hello" );
console.log(b.getName()); // "hello"

2.2 Event Handling

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var paint = {
  color: "red" ,
  count: 0,
  updateCount: function () {
   this .count++;
   console.log( this .count);
  }
};
  
// 事件处理函数绑定的错误方法:
document.querySelector( 'button' )
  .addEventListener( 'click' , paint.updateCount); // paint.updateCount函数的this指向变成了该DOM对象
  
// 事件处理函数绑定的正确方法:
document.querySelector( 'button' )
  .addEventListener( 'click' , paint.updateCount.bind(paint)); // paint.updateCount函数的this指向变成了paint

2.3 Time interval function

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var notify = {
  text: "Hello World!" ,
  beforeRender: function () {
   alert( this .text);
  },
  render: function () {
  
   // 错误方法:
   setTimeout( this .beforeRender, 0); // undefined
  
   // 正确方法:
   setTimeout( this .beforeRender.bind( this ), 0); // "Hello World!"
  }
};
  
notify.render();

2.4 Borrowing the native methods of Array

?
1
2
3
4
var a = {};
Array.prototype.push.bind(a, "hello" , "world" )();
  
console.log(a); // "hello", "world"

3. Browser compatibility of bind() method

4. Compatibility writing of bind()

?
1
2
3
4
5
6
7
8
9
10
11
12
if (!Function.prototype.bind) {
  Function.prototype.bind = function () {
   var self = this , // 保存原函数
    context = [].shift.call(arguments), // 需要绑定的this上下文
    args = [].slice.call(arguments); // 剩余的参数转成数组
   return function () { // 返回一个新函数
    // 执行新函数时,将传入的上下文context作为新函数的this
    // 并且组合两次分别传入的参数,作为新函数的参数
    return self.apply(context, [].concat.call(args, [].slice.call(arguments))); 
   }
  };
}

5. The difference between bind and call/apply methods

Common ground:

Can change the context of function execution;

difference:

bind: does not execute the function immediately, generally used for asynchronous calls and events; call/apply: executes the function immediately.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326065875&siteId=291194637