JavaScript中call,apply和bind方法

这篇博客详细介绍了JavaScript中call、apply和bind的区别及其使用场景。call和apply都用于改变函数内部this的指向,并立即执行函数,区别在于传递参数的方式。bind则返回一个新的函数,保留原函数的this并可以进行柯里化。此外,文中还给出了这三个方法的模拟实现,帮助理解其工作原理。
摘要由CSDN通过智能技术生成

1. 三者的区别

  • call和apply都是为了解决函数调用的时候函数内部this指向的问题,默认第一参数是this指向,其余的都是函数的形参。call的形参用逗号隔开,apply的参数用一个数组接收。
  • call和apply是改变this指向后立即执行函数,而bind是返回一个绑定上下文的新函数,后续可以通过新函数执行。
  • bind函数返回的新函数不可以再通过apply call改变它的this指向。
let a = {value:1};
function foo(name,age) {
    console.log(name);
    console.log(age);
    console.log(this.value);
}
foo.call(a,"lisi",12);          //lisi    12  1
foo.apply(a,["wangwu",13]);     //wangwu  13  1
let f = foo.bind(a);                    //不执行函数foo
f("zhangsan",15);               //zhangsan  15  1
//foo.bing(a)("zhangsan, 15")   //zhangsan  15  1

2.模拟实现call

Function.prototype.mycall = function(context) {
	//判断是不是函数调用了mycall
	if (typeof this !== 'function') {
        throw new TypeError("Not a Function")
    }
	
	//不传参数默认为window
	context = context || window;
	
	//保存调用mycall的函数,foo.call(a) => a.fn = foo
	context.fn = this;
	
	//保存传入的参数
	let args = Array.from(arguments).slice(1);
	
	//调用函数
	let result = context.fn(...args);

	//删除fn
	delete context.fn;
	
	//返回结果
	return result;
	
}

3.模拟实现apply

Function.prototype.myapply(context) {
	if(type this !== 'function') {
		throw new TypeError("Not a function");
	}
	//不传参默认为window
	context = context || window

	//保存调用myapply的函数
	context.fn = this;

	let result;
	
	//判断是否传入了参数
	if(arguments[1]) {
		result = context.fn(...arguments[1]);
	} else {
		result = context.fn()
	}
	//删除函数
	delete context.fn;
	
	//返回结果
	return result;
	
}

4. 模拟实现bind

Function.prototype.bind(context) {
	if (typeof this !== 'function') {
       throw new TypeError("Not a Function")
    }
    //保存调用bind的函数
    const _this = this;
	
	//保存参数
	const args = Array.prototype.slice.call(arguments,1);
	//返回一个函数
	return function F () {
        // 判断是不是new出来的
        if(this instanceof F) {
          // 如果是new出来的
          // 返回一个空对象,且使创建出来的实例的__proto__指向_this的prototype,且完成函数柯里化
          return new _this(...args,...arguments)
        }else{
          // 如果不是new出来的改变this指向,且完成函数柯里化
          return _this.apply(context,args.concat(...arguments))
        }
      } 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值