call apply 和bind 实现以及区别

// 三者的第一个参数都是this需要指向的对象
// 但在后续的参数上只有apply是接收一个数组,call和bind用逗号分开

// call和apply直接调用,返回的是一个值

// 而bind不直接调用,返回的是一个函数形式,执行:foo.bind(obj)()

Function.prototype._call = function(context = window, args) {
    context.fn = this;
    const res = context.fn(...args);
    delete context.fn;
    return res;
}


Function.prototype._apply = function(context = window, args) {
    context.fn = this;
    const res = context.fn(args);
    delete context.fn;
    return res;
}

//真数组 =》类数组转换

// var arr = [1,3,5];
// var obj = {};
// [].push.apply(obj,arr);     // { 0:1, 1:3 , 2:5 , length:3 }

// 类数组 ==> 真数组转换

// 系统自带类数组对象
// var divs = document.querySelectorAll('div');

// 自定义类数组对象

// var obj = {0:'lqs' , 1:18 , length:2};
// var arr = [];   //  真数组

// 在高级的浏览器中使用如下的方法是可以实现类数组对象转换为真数组,但是在 IE8 及其以下是不行的

// [].push.apply(arr,divs);
// [].push.apply(arr,obj);

// 为了兼容 IE8 及其以下的浏览器,需要使用数组的 slice 方法
// 数组的 slice 方法不传递参数的时候是将数组中的元素依次遍历然后放到一个 新的数组 中原样返回

// var arr2 = [].slice.call(obj);

// 一切以数组为输入,并以数组为输出的API都可用来做数组转换

// const arrayLike = {0: 3,1: 4,2: 5,length: 3}

// Array.prototype.slice.call(arrayLike)

// Array.apply(null, arrayLike)

// Array.prototype.concat.apply([], arrayLike)

// Array.prototype.slice.call(arrayLike)

// Array.prototype.map.call(arrayLike, x => x)

// Array.prototype.filter.call(arrayLike, x => 1)

// ES6:Array.from()、... 扩展运算符

// // Array.from();方法用于将类数组对象和可遍历(Iterator)对象转换为真数组
// var obj = {0:'lqs' , 1:18 , length:2};
// var arr = Array.from(obj)   // ['lqs',18]

// ... 扩展运算符
// 适用于 iterable 对象 [...doucmnet.querySelector('div')]
// 但在{length:3}这种情况下会抛出异常
// Uncaught TypeError: object is not iterable (cannot read property Symperty Symbol(Symbol.iterator))[...{length:3}]

// 总结:

// 以上方法中靠谱的数组转换方法

// Array.from(arrayLike)

// Array.apply(null, arrayLike)

// Array.prototype.concat.apply([], arrayLike)

//返回一个绑定了上下文的新函数,不是立即执行的

Function.prototype._bind = function(context = window, ...args) {
    var fn = this;
    return function(...innerArgs) {
        return fn.apply(context, [...args, ...innerArgs]);
    }
}

// var value = 2;
// var foo = {
//     value: 1
// };
 
// function bar(name, age) {
//     return {
// 		value: this.value,
// 		name: name,
// 		age: age
//     }
// };
 
// bar.call(foo, "Jack", 20); // 直接执行了函数
// // {value: 1, name: "Jack", age: 20}
 
// var bindFoo1 = bar.bind(foo, "Jack", 20); // 返回一个函数
// bindFoo1();
// // {value: 1, name: "Jack", age: 20}
 
// var bindFoo2 = bar.bind(foo, "Jack"); // 返回一个函数
// bindFoo2(20);
// // {value: 1, name: "Jack", age: 20}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
call、applybind都是用来改变函数中的this指向的方法。其中,call和apply可以直接调用函数并传递参数,而bind则返回一个新的函数,需要手动调用。 具体实现方案如下: - call的实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数。 3. 结束调用后,删除该属性。 - apply实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数数组。 3. 结束调用后,删除该属性。 - bind实现: 1. 创建一个新的函数,并将原函数作为其中的属性保存起来。 2. 当新函数被调用时,将之前绑定的对象作为this,并传递参数。 3. 返回新函数供后续调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [如何实现call、applybind](https://blog.csdn.net/XIAO_A_fighting/article/details/116701887)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [原生JS实现 call apply bind](https://download.csdn.net/download/weixin_38628990/14046564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值