用人话说清bind

本文详细解析了JavaScript中bind方法的两种主要应用场景:改变this指向和参数固化。通过示例代码展示了如何在事件处理中使用bind确保this的正确指向,以及如何利用bind实现函数柯里化,简化代码。此外,还提供了实际的路由实现和Ajax请求中的应用案例,帮助读者深入理解bind的实用价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bind 常见应用情形主要有两种:

  1. 改变 this 指向;
  2. 参数固化(又叫偏函数,可理解为函数柯里化的简单应用)。

第一种情形很简单,demo如下:

const cat = {
    name: 'xiaoJu',
    say: function () {
        console.log(this.name)
    }
}

cat.say();	  // xiaoJu

const otherCat = {
    name: 'daHuang'
};
cat.say.bind(otherCat)()	// daHuang

cat.say() 很简单,遵循 this 的“谁调用指向谁”的大法,打印出 cat 的 name, 即“xiaoJu”。

cat.say.bind(otherCat)()是什么意思呢?bind() 会创建一个新函数,当这个新函数被调用时,它的 this 值是传给它的第一个参数。所以,这段代码等同于:

let newSay = cat.say.bind(otherCat);
newSay();

bind() 创建了 newSay ,其内容和 cat.say 一模一样,只是它的 this 指向 bind() 的第一个参数,也就是 otherCat。

实际案例如下:

路由实现中有这么一段代码:

Router.prototype.init = function () {
    window.addEventListener('load', this.refresh.bind(this))
    window.addEventListener('hashchange', this.refresh.bind(this))
}

如果不是很了解 bind,这段代码中的 this.refresh.bind(this)将不会使人很明白,当换个写法,就比较好理解:

Router.prototype.init = function () {
    const _this = this;
    window.addEventListener('load', function () {
        _this.refresh()
    })
    window.addEventListener('hashchange', function () {
        _this.refresh()
    })
}

这样就明白很多了,其实就是监听两个事件,然后都执行 Router 实例原型上的 refresh() 方法,为了使this 指向正确,用了 const _this = this; 的写法,当然,以下这样当然也是可以的:

Router.prototype.init = function () {
    window.addEventListener('load', () => {
        this.refresh()
    })
    window.addEventListener('hashchange', () => {
        this.refresh()
    })
}

既然作用只是执行一个方法,如下写法为什么不行呢?

Router.prototype.init = function () {
    window.addEventListener('load', this.refresh)
    window.addEventListener('hashchange', this.refresh)
}

因为这样 refresh 里面的 this 就和Router 实例没关系了,指向就是指向 window 了,为了把 this 指向纠正过来,bind 就派上用场了:

Router.prototype.init = function () {
    window.addEventListener('load', this.refresh.bind(this))
    window.addEventListener('hashchange', this.refresh.bind(this))
}


demo 和实际案例解释完毕,来看第二种情形:

function print(name, day, where, doSomething) {
    console.log(`${name}${day}${where} ${doSomething}`)
}

print('小明', '昨天', '操场', '打篮球');		// 小明 于 昨天 在 操场 打篮球
print('小明', '昨天', '田径场', '跑步');		// 小明 于 昨天 在 田径场 跑步
print('小明', '昨天', '林荫小道', '散步');	// 小明 于 昨天 在 林荫小道 散步

print 函数被调用多次,但是每次调用,前两个参数都是固定的,但是也不能写死在函数内部,因为或许下几次这两参数就会变了。那么有不有一个方法,能暂时的固定这两个参数呢,答案是有的,就是用 bind() 来实现:

const print2 = print.bind(null, '小明', '昨天');
print2('操场', '打篮球');	// 小明 于 昨天 在 操场 打篮球
print2('田径场', '跑步');	// 小明 于 昨天 在 田径场 跑步

那如果前面参数变了呢?重新 bind() 一次就好:

const print3 = print.bind(null, '小红', '前天');
print3('图书馆', '看书');   // 小红 于 前天 在 图书馆 看书
print3('音乐厅', '唱歌');   // 小红 于 前天 在 音乐厅 唱歌

类似的实际案例常见于 ajax 请求中,具体不贴代码了,小小一个改造,代码会简洁很多,这可以理解为函数柯里化思想的一个简单应用。


一句话日记:但愿如今不停歇的努力,能弥补大学浪费的那几年

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值