javascript基础之bind、call、apply方法的区别以及如何手动实现

改变this的指向可以用bind,call,apply方法,那这三个方法有什么区别呢?又如何手动实现这三个方法呢?且往下看:

1、bind、call、apply的区别是什么?

bind被称为是绑定函数,其函数内部的this指向创建它时传入bind的第一个参数,而传入bind的第二个以及后面的参数则作为原来函数的参数调用原函数,另外bind不会立即执行,而是返回了一个新的函数。

call和apply都是为了改变函数内部的运行上下文,apply和call的调用返回函数执行结果。调用call或apply方法,那么this指向他们的第一个参数,apply的第二个参数是一个参数数组,call的第二个及其以后的参数都是数组里面的元素,就是说要全部列举出来;

2、bind、call、apply的怎么用?

bind语法:

func.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg 当绑定函数被调用时,该参数会作为原函数运行时的this指向。当使用new 操作符调用绑定函数时,该参数无效。
arg1, arg2, ... 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。
call语法:

fun.call(thisArg, arg1, arg2, ...)
thisArg::在fun函数运行时指定的this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
arg1, arg2, ... 指定的参数列表。
apply语法:

fun.apply(thisArg, [argsArray])
thisArg: 在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
argsArray: 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。

总结:

  • 当我们使用一个函数需要改变this指向的时候才会用到call,apply,bind
  • 如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用bind
  • 如果你要传递的参数不多,则可以使用fn.call(thisObj, arg1, arg2 ...)
  • 如果你要传递的参数很多,则可以用数组将参数整理好调用fn.apply(thisObj, [arg1, arg2 ...])

如何手动实现bind、call、apply? 

myBind的实现:

Function.prototype.myBind = function() {
    var _this = this;
    var context = [].shift.call(arguments)
    var args = [].slice.call(arguments)
    return function() {
        return _this.apply(context, [].concat.call(args, [].slice.call(arguments)));
    }
}

myCall的实现:

Function.prototype.myCall = function(context) {
    var context = context || global
    context.fn = this
    var arr = []
    for (var i=0,len=arguments.length;i<len;i++) {
        arr.push("arguments[" + i + "]")
    }
    var result = eval("context.fn(" + arr.toString() + ")")
    delete context.fn;
    return result;
}

myApply的实现:

Function.prototype.myApply = function(context, arr) {
    var context = context || global
    context.fn = this
    var result
    if (!arr) {
        result = context.fn()
    } else {
        var args = [];
        for (var i=0,len=arr.length;i<len;i++) {
            args.push("arr[" + i + "]")
        }
        result = eval("context.fn([" + args.toString() + "])")
    }
    delete context.fn;
    return result
}

bind,call,apply大概就是这么多介绍,忘指导。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值