javascript中bind()函数实现和应用以及多次bind的结果和参数位置的思考

本文深入探讨JavaScript中的bind()方法,包括其在ECMAScript-262第五版中的引入,作用于改变函数上下文的this值,以及在事件处理和应用场景中的使用。此外,文章还详细分析了bind方法的多次绑定效果和参数顺序的复杂性。

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

概述

在ECMA-262第五版引入了bind()方法,该方法创建一个新函数。

语法

fn.bind(context[, arg1[, arg2[, ...]]])
第一个参数context将成为返回的新函数的this对象
第二个及以后的参数加上绑定函数运行时本身的参数按照顺序,将作为新函数的擦书

实现原理

Function.prototype.bind = function (context) {
	// 调用Array的方法来切割伪数组对象arguments
	// 由此获此bing()方法传进来的第二个及以后的参数
	var args = Array.prototype.slice.call(arguments, 1);
	return function () {
		return this.apply(context, args.concat(Array.prototype.slice.call(arguments)));
	};
};
其核心思想就是返回一个函数,函数里是通过用apply指定this值的原函数的返回值。

常见应用场景

  • 改变对象方法里this的值
var ob = {
	name: 'joe',
	getName: function () {
		alert(this.name);
	}
};
// 改变getName方法里原本的this对象为新对象{name: 'haha'}
var app = ob.getName.bind({name: 'haha'});
app();
  • 改变事件处理函数里的this值,因为在事件处理函数中的this指向的是dom元素,在某些情况下我们需要改变这个this值
$(function () {
	// 这里的e是定义为原函数里的参数,但是返回的新函数没有定义参数
	// 因此相当于function(e) {}
	$('.btn').on('click', function(e) {
		alert(this.name);
	}.bind({name: 'joe'}));
});

多次绑定bind方法

那么你有没有想过,如果使用bind()方法多次绑定,最终得到的this会是哪个绑定的呢?
function say() {
	alert(this.x);
};
var a = say.bind({x: 1});
var b = a.bind({x: 2});
b(); // 这里会输出1还是2呢?
这里我对这手机想了好久也没绕出来,最后代码一些就明白了。。。那你想到结果了吗?

那么我们不妨先分析一下

say函数使用bind方法,穿进去了一个对象,相当于
var a = function() {
	return say.apply({x: 1});
};
如果我们对得到的函数a再进行绑定,则相当于
var b = function() {
	return a.apply({x: 2});
};
var b = function() {
	return function() {
		return say.apply({x: 1});
	}.apply({x: 2});
};
这样虽然我们改变了函数a里this的值,但是最后函数say里的this的值还是由第一次绑定时的参数决定,而与函数a中的this值无关

多次绑定的结果

所以无论使用bind绑定多少次,最终原函数的this值是由第一次绑定传的参数决定的。

多次绑定参数的顺序

function say() {
	alert(this.x);
};
var a = say.bind({x: 1},1,2,3);
var b = a.bind({x: 2},4,5,6);
a(7,8,9);
b(7,8,9); 
// 此时原函数say参数的顺序的怎样的呢?
// 是[4,5,6,1,2,3,7,8,9]还是[1,2,3,4,5,6,7,8,9]
首先对say使用bind方法,会改变函数say的this值,和 “内置”参数。所以
a(7,8,9)
的参数组成是: 内置的参数 + 调用时传入的参数 = 最终函数,即[1,2,3]+ [7,8,9] = [1,2,3,7,8,9]
而对函数a使用bind方法,只会改变函数a的this值,和往函数a里 “内置”参数。所以
b(7,8,9)
的参数组成是:[1,2,3](在函数say内置的参数) + [4,5,6](在函数a内置的参数) + [7,8,9] = [1,2,3,4,5,6,7,8,9]

总结

对哪个函数使用bind()方法即改变这个函数的this值,和内置其参数,或者说像克里化一样理解,先预置好参数
var a = say.bind({x:1},1,2,3); // 是改变函数say的this值,和在函数say上预置参数1,2,3
var b = a.bind({x: 2}, 4,5,6); // 是改变函数a的this,和在函数a上预置预置参数4,5,6














评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值