模拟apply/call/bind

call

先看call

call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法。

两点:

  1. call 改变了 this 的指向
  2. 执行了

实现思路, 举个例子:

	var foo = {
	    value: 1
	};
	
	function bar() {
	    console.log(this.value);
	}
	
	bar.call(foo); // 1

想想: 我们把bar函数挂载到foo下不就行了吗

	var foo = {
	    value: 1,
	    bar: function() {
	        console.log(this.value)
	    }
	};
	
	foo.bar(); // 1

ok, 仔细想想, 要求如下:

  1. 将函数设为对象的属性
  2. 若传入为null, 指向window
  3. 可能带有参数
  4. 执行该函数
  5. 可能有返回值
  6. 删除该函数

实现es5:

	Function.prototype.call = function (context) {
		// 若传入为null, 指向window
	    var context = context || window;
	    context.fn = this;
	    // 拿到参数
	    var args = [];
	    for(var i = 1, len = arguments.length; i < len; i++) {
	        args.push('arguments[' + i + ']');
	    }
		// 执行
	    var result = eval('context.fn(' + args +')');
		// 删除
	    delete context.fn
	    // 返回值
	    return result;
	}

实现es6:

	Function.prototype.call = function (context) {
		// 若传入为null, 指向window
	    var context = context || window;
	    context.fn = this;
	    // 拿到参数
	    var [a, ...args] = [...arguments];
		// 执行
	    var result = context.fn(...args);
		// 删除
	    delete context.fn
	    // 返回值
	    return result;
	}
apply

与call一致, 只是参数格式是数组而已

bind

bind() 方法会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。

bind 函数的两个特点:

  1. 返回一个函数
  2. 可以传入参数

实现es5:

Function.prototype.bind = function (context) {
    var self = this;
    // 获取bind2函数从第二个参数到最后一个参数
    var args = Array.prototype.slice.call(arguments, 1);

    return function () {
        // 这个时候的arguments是指bind返回的函数传入的参数
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(context, args.concat(bindArgs));
    }

}

实现es6:

Function.prototype.bind = function (context) {
    var self = this;
    // 获取bind2函数从第二个参数到最后一个参数
    var [a, ...args] = [...arguments];

    return function () {
        // 这个时候的arguments是指bind返回的函数传入的参数
        var bindArgs = [...arguments];
        return self.apply(context, args.concat(bindArgs));
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值