bind 的功能介绍

bind() 方法会创建一个新函数,当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的的参数。
注意点:

  1. 跟 call、apply 一样都是会绑定 this,但 bind 不会立即执行,而是返回一个函数等待用户的执行。
  2. bind 可以预存参数。
  3. bind 返回的新函数作为 new 构造函数调用时会忽略默认提供的 this,但预存参数不会。
  1. // 用法
  2. var foo = {
  3. value: 1
  4. };
  5. function bar() {
  6. console.log(this.value);
  7. }
  8. // 返回了一个函数
  9. var bindFoo = bar.bind(foo);
  10. bindFoo() // 1
  11. // new 构造函数调用
  12. function bar(name, age) {
  13. this.habit = 'exercise';
  14. console.log(this.value);
  15. console.log(name);
  16. console.log(age);
  17. }
  18. bar.prototype.friend = 'frank';
  19. var bindFoo = bar.bind(foo, 'xxiang');
  20. var obj = new bindFoo('22');
  21. // undefined
  22. // xxiang
  23. // 22
  24. console.log(obj.habit) // exercise
  25. console.log(obj.friend) // frank

模拟实现

  1. Function.prototype.bind = function (context) {
  2. // 判断是否为函数,否则抛出一个错误。
  3. if (typeof this !== "function") {
  4. throw new Error("context is not function");
  5. }
  6. var self = this;
  7. var args = Array.prototype.slice.call(arguments, 1);
  8. var fNOP = function () {};
  9. var fBound = function () {
  10. var bindArgs = Array.prototype.slice.call(arguments);
  11. // 用 apply 来实现的好处是直接可以用类数组(arguments)作参数。
  12. // 判断是否是 new 构造函数调用。
  13. return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
  14. }
  15. // 借助空函数做中转。
  16. // 如果写成 fBound.prototype = this.prototype,共享一个对象不好。
  17. fNOP.prototype = this.prototype;
  18. fBound.prototype = new fNOP();
  19. // 返回函数是因为可能需要执行函数的返回结果。
  20. return fBound;
  21. }

参考:
[1] JavaScript深入之bind的模拟实现
[2] MDN