bind方法的阐述

2 篇文章 0 订阅

JavaScript中,bind() 方法够改变对this的引用,在上下文中创建一个新函数不会被立即执行(对绑定函数的调用,并且可以指定特定的this,成为一个新的函数,就好像是深拷贝一般),在平常工作中经常用到,并且也是面试的高热词汇,这里就顺带将它进行一些解释:

语法

fn.bind(thisArg, arg1[, arg2[, ...]]])
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。当使用new运算符构造,所提供的this将会被忽略,但前置参数仍会提供给模拟函数。当bind()的参数为空时,this指向全局对象。如浏览器中的window。它的返回是一个原函数的拷贝,并拥有指定的 this 值和初始参数。

示例

1、在JavaScript经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,期望方法中的 this 是原来的对象(比如在回调中传入这个方法)。如果不做特殊处理的话,一般会丢失原来的对象。基于这个函数,用原始的对象创建一个绑定函数,巧妙地解决了这个问题:

this.x = 9;    // 在浏览器中,this 指向全局的 "window" 对象
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX();   
// 返回 9 - 因为函数是在全局作用域中调用的

// 创建一个新函数,把 'this' 绑定到 module 对象
// 新手可能会将全局变量 x 与 module 的属性 x 混淆
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81

2、bind() 能够使一个函数拥有预设的初始参数(默认值)。只要将这些参数作为 bind() 的参数写在 this 后面。当绑定函数被调用时,这些参数会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们后面(也就是说目标函数的参数会优先于调用传递的参数)。

function list() {
  return Array.prototype.slice.call(arguments);
}

function addArguments(arg1, arg2) {
    return arg1 + arg2
}

var list1 = list(1, 2, 3); // [1, 2, 3]

var result1 = addArguments(1, 2); // 3

// 创建一个函数,它拥有预设参数列表。
var leadingThirtysevenList = list.bind(null, 37);

// 创建一个函数,它拥有预设的第一个参数
var addThirtySeven = addArguments.bind(null, 37); 

var list2 = leadingThirtysevenList(); 
// [37]

var list3 = leadingThirtysevenList(1, 2, 3); 
// [37, 1, 2, 3]

var result2 = addThirtySeven(5); 
// 37 + 5 = 42 

var result3 = addThirtySeven(5, 10);
// 37 + 5 = 42 ,第二个参数被忽略

3、在默认情况下,使用 window.setTimeout() 时,this 关键字会指向 window (或 global)对象。当类的方法中需要 this 指向类的实例时,你可能需要显式地把 this 绑定到回调函数,就不会丢失该实例的引用。

function LateBloomer() {
  this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// 在 1 秒钟后声明 bloom
LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.declare = function() {
  console.log('I am a beautiful flower with ' +
    this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();  // 一秒钟后, 调用 'declare' 方法

4、可以通过bind实现一些共有方法。

    var fly = function(){
      //fly
      console.log('I am a ' + this.name + ', I can fly');
    };
    
    var bird = {
      name: 'bird'
    };
    var plane = {
      name: 'plane'
    };
    
    fly.bind(bird)(); //I am a bird, I can fly
    fly.bind(plane)();//I am a plane, I can fly

5、针对特定的this调用某些方法。写起来比较麻烦,这个时候就可以使用bind创建一个shortcut方便调用。 

/*你可以用 Array.prototype.slice 来将一个类似于数组的对象(array-like object)转换成一个真正的数组*/
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.apply.bind(unboundSlice);

// ...

slice(arguments);

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值