js模拟实现call和apply方法

call

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

例子:


	var foo = {
		
		value:2
	}

	function bar() {
		console.log(this.value)
	}
	bar.call(foo) // 2

从这个例子中可以看出两点:

  • call 改变了 this 的指向,指向到 foo
  • bar函数也执行了

模拟实现基本原理

上述例子试想当调用 call 的时候,把 foo 对象改造成如下:

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

foo.bar(); // 2

这个时候的this就指向了foo函数了,但是foo对象又添加了一个多余的属性,因此我们需要bar用delete给删除就行了。

因此模拟的步骤分为三步:

  1. 将函数设为对象的属性
  2. 执行该函数
  3. 删除该函数

以上述例子:

// 第一步
foo.fn = bar
// 第二步
foo.fn()
// 第三步
delete foo.fn

fn 是对象的属性名,反正最后也要删除它,所以起成什么都无所谓。

  • 最终的实现及应用
	var value = 3

	var foo = {
		
		value:2
	}

	function bar(name,age) {

		console.log(this.value)

		console.log(name)

		console.log(age)
	}
	
	Function.prototype.call2 = function (context) {
		 //没传参数或者为null是默认是window
		var context = context || window
		 // 首先要获取调用call的函数,用this可以获取
		context.fn = this

		var args = []

		for(var i = 1;i<arguments.length;i++){

				args.push('arguments[' + i + ']')
		}

		eval('context.fn('+args+')')

		// 执行了args.push('arguments[' + i + ']')后
		// args = [ 'arguments[1]', 'arguments[2]' ]包含2个字符
		// 然后执行eval('context.fn(' + args + ')')
		// +令 args 执行 args.toString() 相当于eval('context.fn(' + ‘arguments[1], arguments[2]’+ ')')
		// 字符串合并,即eval('context.fn( arguments[1], arguments[2] )')
		// 执行context.fn( arguments[1], arguments[2] )

		delete context.fn

	}
	bar.call2(null)// 3  undefinde undefinde

	bar.call2(foo,'cc',18) // 2  cc 18

apply

实现原理和call差不多

Function.prototype.apply = function (context, arr) {
    var context = Object(context) || window;
    context.fn = this;

    var result;
    if (!arr) {
        result = context.fn();
    }
    else {
        var args = [];
        for (var i = 0, len = arr.length; i < len; i++) {
            args.push('arr[' + i + ']');
        }
        result = eval('context.fn(' + args + ')')
    }

    delete context.fn
    return result;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值