call apply bind一些应用以及简单重写

本文深入探讨了JavaScript中如何将类数组对象转换为数组,利用`Array.prototype.slice.call()`方法实现。此外,还讲解了`bind`方法的使用,包括其在事件处理函数中的应用和避免立即执行的场景。最后,展示了如何重写`call`和`bind`方法,以理解其内部工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类数组转为数组(call apply)

  • arguments 是类数组,无法直接调用 Array.prototype 上的方法
function mySum() {
    // 我们可以把 arguments 转为数组
    let ary = Array.prototype.slice.call(arguments);
    console.log(ary) // => [1, 2, 3, 4, 5]
    // 这样就可以调用数组的方法了
    let result = 0;
    // 也可以直接把数组原型链上的函数 this 改成 arguments
    // 大多数方法都可以这样被类数组调用
    Array.prototype.forEach.call(arguments, item => {
        result += item;
    });
    return result;
}
let sum = mySum(1, 2, 3, 4, 5);
console.log(sum); // => 15

bind 不立即执行的应用

let obj = {
    name: 'patrick',
    age: 12
}
function fn(x, y) {
    console.log(this, x, y);
}
window.onclick = fn; // this => window x => PointerEvent y => undefined
// 假设我们想让 fn 的 this 指向 obj,并传递参数
window.onclick = fn.call(obj, 10, 20);
// 调用 call 会立即执行,在事件未触发时,fn 已经被执行
window.onclick = fn.bind(obj, 10, 20);
// 调用 bind 解决此问题,bind 不会立即执行

重写 call

Function.prototype.call = function call(context, ...params) {
    context = Object(context); // 把非引用类型值转为引用类型值
    let proxy = Symbol('fn'); // 用 Symbol 防止原对象属性重名
    context[proxy] = this;
    let result = context[proxy](...params);
    delete context[proxy];
    return result;
}
let obj = {
    name: 'patrick',
    age: 12
};
function fn(x, y) {
    console.log(this, x, y);
    return x + y;
};
fn.call(obj, 10, 20);

重写 bind

Function.prototype.bind = function bind(context, ...params) {
    let that = this;
    return function proxy(...innerParams) {
        params.concat(innerParams);
        that.call(context, ...params);
    }
}
let obj = {
    name: 'patrick',
    age: 12
};
function fn(x, y) {
    console.log(this, x, y);
    return x + y;
};
window.onclick = fn.bind(obj, 10, 20);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值