JS & 改变 this 的三大利器:call / apply / bind

一、call

每个函数都有 call 方法,call 可以改变函数当前的 this 环境(对象),记住这点很重要。

例子1:给对象换新欢

const Jack = {
	hisGirlName: 'Candy',
	getMyGirlFriend() {
  		console.log(this.hisGirlName)
  	}
}
const John = {
	hisGirlName: 'Lili',
}
Jack.getMyGirlFriend.call(John) // 打印:Lili

例子2:偷天换日的感觉真是太棒了

function Jack() {}
Jack.prototype.bankAccount = '100'
Jack.prototype.getMyMoney = function() {
	console.log('Money:', this.bankAccount)
}

function Linda() {}
Linda.prototype.bankAccount = '100W';

const superPerson = new Jack()
console.log(superPerson.getMyMoney()) // 打印:100
console.log(superPerson.getMyMoney.call(new Linda)) // 打印:100W

二、apply

每个函数都有 apply 方法,它与 call 的作用是一模一样的,唯一的区别是,它的传参要用数组形式。

例子1:简化获取列表中的最值方式

const nums = [22,33,2,14,10,100]
const maxNum = Math.max.apply(null, nums)
const minNum = Math.min.apply(null, nums)
console.log(maxNum, minNum) // 打印:100 2

提示:apply 第二个参数虽是数组形式,但函数接受时是以单个参数形式,理清这点是有必要的,这也是 Math.max 能够识别“数组”参数的原因。

例子2:给对象换新欢

和 call 一样,这里就不举例了。

三、bind

每个函数都有 bind 方法,它与前面的 call/apply 不同,它并不会立即调用函数,而是返回一个新的函数(通常也叫偏函数)并绑定调用时的传递的 this 执行环境 记住这点很重要。

例子1:先存起来,下次再用

for (var i = 0; i < 5; i ++) {
	var self = this
 	setTimeout(function(num) {
		console.log(num)
	}.bind(self, i), 1000)
}
// 打印:0 1 2 3 4

解释:bind 绑定了当前所属环境,这里的 i 是按值传参,于是,bind 每次绑定的值便是 i 当前的那个值。当每个定时器执行后将读取当前所处环境的参数值。

利用传参是按值传递的特性,上面的代码也可以改成这样的:

for (var i = 0; i < 5; i ++) {
	var fn = function(num) { return function() { console.log(num) } }
	setTimeout(fn(i), 1000)
}

四、留意

  1. call/applybind 传递指向环境非 this 而是 null 时,此时 null === windows 全局环境。
  2. call/apply/bind 可以混合使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cookcyq

请作者喝杯暖暖的奶茶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值