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
- javascript中bind()函数实现和应用以及多次bind的结果和参数位置的思考
- "lambda"和“bind”的初步思考
- Boost关于bind的使用以及函数对象和传递参数的问题
- javascript对象详解以及call、apply和bind的使用
- 函数bind的实现
- es5 bind和es3函数模拟的bind的区别
- 深入浅出Javascript中apply、call和bind以及它们的妙用
- JavaScript 之 call和apply,bind 的模拟实现
- javascript中apply、call和bind的区别
- JavaScript中apply、call和bind的区别
- javascript中apply、call和bind的区别
- javascript中apply、call和bind的区别
- JavaScript 中apply()、call()和bind()方法的使用
- javascript中apply、call和bind的区别
- javascript中apply、call和bind的区别
- javascript中apply、call和bind的区别
- JavaScript中apply()、call()和bind()的相似与区别
- javascript中:call、apply和 bind的简单使用方法
- 移动应用开发必备工具盘点
- 第4周项目2 建设“单链表”算法库
- Spring实战(第3版)读书总结
- Check if paper-checkbox is checked
- 第四周项目4-建立双链表算法库
- javascript中bind()函数实现和应用以及多次bind的结果和参数位置的思考
- 手动为sublime text3添加package control插件
- ./configure -build,-host,-target设置
- 面试再谈struct和union大小问题
- 第3周项目4 顺序表应用问题(1)
- js页面滚动浮动层智能定位(jQuery)实例页面
- 第4周 项目3-单链表应用
- Servlet 3.0 新特性详解
- UITableViewCell中设置不同图片尺寸相同以及设置图片为圆形的方法