JS中的函数绑定以及实现函数柯里化

27 篇文章 0 订阅
20 篇文章 1 订阅

假设页面有个按钮btn,实现点击打印message信息和事件类型(暂只介绍ES5,js新的提案中提出了“函数绑定”(function bind)运算符::)。

第一步:

var handler = {
    message:'hello world',
    handleClick:function(e){
        console.log(this.message)
        console.log(e.type)
    }
}

btn.addEventListener('click', handler.handleClick ,false);

预期中,结果打印hello world、click,结果却是:undefined、click.

根据闭包 的特性,上面代码中handler.handleClick()的上下文环境没有得到保留,所以在函数内部this的指向不是handler而是btn对象,所以不存在message属性。

第二步:

我们可以使用一个闭包去修复上面this指向问题。

var handler = {
    message:'hello world',
    handleClick:function(e){
        console.log(this.message)
        console.log(e.type)
    }
}

btn.addEventListener('click', function(e){
    handler.handleClick(e);
} ,false)

结果打印hello world、click,没有问题。

第三步:

我们可以构建一个通用的函数bind(),用于将函数绑定到指定上下文环境。

function bind(fn,context){
    return function(){
        fn.apply(context, arguments)
    }
}

btn.addEventListener('click', bind(handler.handleClick,handler) ,false)

结果打印hello world、click,没有问题。

bind()中使用了apply改变了fn的上下文环境。arguments是内部匿名函数的,而非bind的。所以可以拿到对应的event参数。

bind的简单使用:

Function.prototype.bind():bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

btn.addEventListener('click', handler.handleClick.bind(handler) ,false)

结果打印hello world、click,没有问题。

关于bind的Polyfill,MDN介绍的很详细,用于兼容部分浏览器。

第四步:

使用函数柯里化,加入额外参数。

var handler = {
    message:'hello world',
    handleClick:function(params, e){
        console.log(this.message)
        console.log(e.type)
        console.log(params)
    }
}

function bind(fn,context){
    var fnArgs = Array.prototype.slice.call(arguments, 2);
    return function(){
        var innerArgs = Array.prototype.slice.call(arguments);
        var finalArgs = fnArgs.concat(innerArgs);
        fn.apply(context, finalArgs)
    }
}

btn.addEventListener('click', bind(handler.handleClick,handler,'first args') ,false)

结果打印hello world , click , first args

ES5的 bind() 方法也实现函数柯里化,只要在 this 的值之后再传入额外参数

var handler = {
    message:'hello world',
    handleClick:function(params1, params2, e){
        console.log(this.message)
        console.log(e.type)
        console.log(params1)
        console.log(params2)
    }
}


btn.addEventListener('click', handler.handleClick.bind(handler, 'first args', 'second args') ,false)

结果打印hello world , click , first args, second args

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值