js手写bind,apply,call

js手写bind,apply,call

一.手写bind

// 模拟 bind
Function.prototype.bind1 = function() {
    //不知道bind传了多少个参数
    // 将参数拆解为数组
    const args = Array.prototype.slice.call(arguments) //相当于arguments.toArray().slice()
    
    // 获取 this(数组第一项:{x:100}),并改变原数组
    const t = args.shift()

    // fn1.bind(...) 中的 fn1
    const self = this

    // 返回一个函数
    return function() {
        return self.apply(t, args)
    }
}

function fn1(a, b, c) {
    console.log('this', this)
    console.log(a, b, c)
    return 'this is fn1'
}

const fn2 = fn1.bind1({ x: 100 }, 10, 20, 30) //bind第一个参数传的是this,后面的参数传递的是真正的函数参数
const res = fn2()
console.log(res)
//上面看不懂看第二种
Function.prototype.myBind = function() {
    const obj = arguments[0];
    const arr = [];
    for (let i = 1; i < arguments.length; i++) {
        arr.push(arguments[i]);
    }
    const self = this;
    return function() {
        return self.apply(obj, arr);
    }
}


function fn1(a, b, c) {
    console.log(a, b, c);
    console.log('this', this.x);
    return 'this is bind'
}

let fn2 = fn1.myBind({ x: 100 }, 10, 20, 30);
let res = fn2();
console.log(res);

二.手写call

Function.prototype.myCall = function() {
    var object = arguments[0];
    // console.log(arguments[0]);
    var arr = [];
    for (var i = 1; i < arguments.length; i++) {
        arr.push(arguments[i]);//注意循环从i=1开始,把第一个参数去掉
    }
    object.__proto__.fn = this;//此处运用隐式原型,为了下面能够delete掉
    var result = object.fn(...arr); //...扩展运算符将一个数组转为用逗号分隔的参数序列。
    delete object.__proto__._fn;
    return result;
}

function fn1(a, b, c) {
    console.log('this', this)
    console.log(a + b + c);
    return 'is bind success';

}

let res = fn1.myCall({ x: 100 }, 20, 20, 30);
console.log(res);

三.手写apply

Function.prototype.myApply = function(object, arr) {
    object.__proto__._fn = this;
    var result = object._fn(...arr);
    delete object.__proto__._fn;
    return result;
}

function fn1(a, b, c) {
    console.log('this', this)
    console.log(a + b + c);
    return 'is bind success';

}

let res = fn1.myApply({ x: 100 }, [10, 20, 30]);
console.log(res);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值