实现call()、apply()、bind()

关于call()、apply()
概念:允许为不同的对象分配和调用属于一个对象的函数/方法

 - 他们作用相同,只是传的参数不同(apply接收的是函数运行的作用域this,以及一个参数数组;而call却是将数组列举出来)

实现apply方法:

其实模拟的步骤也就是三步:

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

实现如下:


Function.prototype.my_apply = function(context){
	// this参数如果传null或者不传,应该指向window
	var context = context || window
	// symbol保证context.fn的唯一性
	const fn = Symbol('fn')
	// 获取调用call的函数,用this获取
	context.fn = this
	// 获取传入的数组参数
	var args = arguments[1]
	// 执行该函数
	var result
	if (!args){
		result=context.fn()
	} else {
		result = context.fn(...args)
	}
	// 删除该函数
	delete context.fn
	return result
};

在这里插入图片描述

实现call()
Function.prototype.my_apply = function(context){

	// this参数如果传null或者不传,应该指向window
	var context = context || window
	// symbol保证context.fn的唯一性
	const fn = Symbol('fn')
	// 获取调用call的函数,用this获取
	context.fn = this
	// 获取传入的数组参数
	var args = []
	// 执行该函数
	var result
	if (!args){
		result=context.fn()
	} else {
		for(var i=1; i<arguments.length; i++){
			args.push('arguments[' + i + ']')
		}
		result = eval('context.fn(' + args + ')')
	}
	// 删除该函数
	delete context.fn
	return result
};

在这里插入图片描述
其实二者里面分别用了… 和eval两种方式,都是可以随便用的一个效果,只是我为了记住,所以分别写了。

eval():可以计算某个字符串,并执行里面的js代码(相当于可以把eval看作< script >标签)

为什么要这样用eval?不能直接将多个参数使用join来转成数组吗?
在这里插入图片描述
如图,不可以 !!!!!!这样是个字符串 ,也就变成一个参数了

关于bind()
bind()方法是创建一个新的函数,在bind()被调用的时候,这个新函数的this被指定为bind()的第一个参数,而其余参数将作为新函数的参数,供调用时使用

举个栗子:🌰
在这里插入图片描述
在这里插入图片描述
如上两图,一个打印undefined, 一个打印‘hi??’就是因为this指向的问题。第一个外层this指向window,要想取到那个值,就必须this指向对应的上下文。
要想模拟,我们知道bind有两个特点:

  1. 返回一个函数
  2. 可以传入参数
Function.prototype.my_bind = function (context) {
    if (typeof this !== "function") {
      throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
    }
    var self = this;
    // 获取函数的数据参数
    var args = Array.prototype.slice.call(arguments, 1);
    var fNOP = function () {};
    var fBound = function () {
    // 这个时候的arguments是bind返回的函数时传入的参数
        var bindArgs = Array.prototype.slice.call(arguments);
        // 判断是否为构造函数,如果是构造函数,this指向实例,如果为普通函数,this指向window
        return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
    }
    // 修改返回函数的prototype为绑定函数的prototype
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值