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

来源:互联网 发布:vx软件 编辑:程序博客网 时间:2024/06/05 11:57

概述

在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,3var b = a.bind({x: 2}, 4,5,6); // 是改变函数a的this,和在函数a上预置预置参数4,5,6














0 0
原创粉丝点击