js中call、apply和bind的介绍(区别)及实现

js中call、apply和bind主要用于改变调用函数(或方法)中this的指向

区别

  1. call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。
  2. bind()方法的用法和call()方法类似,区别就是bind()不会立即执行,可二次传参后再执行。

一、call、apply和bind的介绍

(1) Function.prototype.call()
call() 方法使用一个指定的 this 值和参数来调用一个函数。

语法:function.call(thisArg, arg1, arg2, ...)
参数:
thisArg: 在 function 函数运行时使用的 this 值。非严格模式下,若指定为 null 或 undefined 时会自动替换为指向全局对象。
arg1, arg2, …: 指定的参数列表。

应用举例:


var obj1 = {name: 'js1', fn: function() {return this.name}}
var obj2 = {name:'js2'}

console.log(obj1.fn()); //js1
console.log(obj1.fn.call(obj2)); //js2
//当一个object没有某个方法,但是其他的有,可以借助call或apply用其它对象的方法来操作

(2) Function.prototype.apply()
方法调用一个具有给定 this值的函数,以及作为一个数组(或类似数组对象)提供的参数。

语法:func.apply(thisArg, [arg1,arg2,...])

应用举例:

var obj1 = {name: 'js1', fn: function() {return this.name}}
var obj2 = {name:'js2'}

console.log(obj1.fn()); //js1
console.log(obj1.fn.apply(obj2)); //js2

(3) Function.prototype.bind()
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

语法:function.bind(thisArg, arg1, arg2, ...)

应用举例:

var obj1 = {name: 'js1', fn: function() {return this.name}}
var obj2 = {name:'js2'}

console.log(obj1.fn()); //js1
console.log(obj1.fn.bind(obj2)); //fn
console.log(obj1.fn.bind(obj2)()); //js2

二、call、apply和bind的实现

call的内部实现

//call的内部实现
Function.prototype.call = function(context) {
    let cxt = context || window;
    cxt.func = this;
    //获取实参
    let args = Array.from(arguments).slice(1);
    let res = arguments.length > 1 ? cxt.func(...args) : cxt.func();
    delete cxt.func;
    return res;
}
//arguments:接受所有实参的伪数组

apply的内部实现

//apply的内部实现
Function.prototype.apply = function(context) {
    let cxt = context || window;
    cxt.func = this;
    let res = arguments[1].length > 0 ? cxt.func(...arguments[1]) : cxt.func();
    delete cxt.func;
    return res;
}

bind内部实现

//bind内部实现
Function.prototype.bind = function(context) {
    let cxt = JSON.parse(JSON.stringify(connext)) || window;//深拷贝
    cxt.func = this;
    //获取实参
    let args = Array.from(arguments).slice(1);
    //返回函数
    return function() {  //没有立即执行的核心
        let allArgs = args.concat(Array.from(arguments));
        return allArgs.length > 0 ? cxt.func(...allArgs) : cxt.func();
    }
}
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值