JS中call,apply,bind改变this指向异同分析

call,apply,bind相同点都是改变this指向,指向传入的thisObj的上下文环境。

不同点

对于第二个参数,call参数必须一一列举出来,apply传入的是一个argment对象或者数组,bind①bind的返回值是函数;②后面的参数的使用也有区别

1、call方法:
语法:call([thisObj,[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象thisObj替换当前对象。
说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

		function sum(num1,num2){
			return num1+num2;
		}		
		function callSum(num1,num2){
		//将sum函数调用到当前callSum环境下执行,并传入sum函数需要的参数
			return sum.call(this,num1,num2);
		}
		console.log(callSum(20,20));

2、apply:
语法:apply(thisObj,数组参数)
定义:应用某一个对象的一个方法,用另一个对象thisOb替换当前对象
说明:如果参数不是数组类型的,则会报一个TypeError错误。

		function sum(num1,num2){
			return num1+num2;
		}		
		function applySum1(num1,num2){
			return sum.apply(this,[num1,num2]);
		}
		function applySum2(num1,num2){
			return sum.apply(this,arguments);
		}
		console.log(applySum1(30,20));
		console.log(applySum2(10,20));

3、bind:
在EcmaScript5中扩展了叫bind的方法(IE6,7,8不支持),bind与call很相似,,例如,可接受的参数都分为两部分,且第一个参数都是作为执行时函数上下文中的this的对象。手写一个自定义的bind函数,如下:
不清楚this指向的可以点击查看阮一峰老师的博文

		Function.prototype.customeBind2 = function(thisObj,...list){
			let self = this;//目标函数
			console.log(this);//this指向下面的函数fun,即返回的新函数				
			let Bound = function(...arg2){
				// 如果这个函数作为了构造函数,那么目标函数的this,应该执行的是实例对象
				// 如果这个不是作为构造函数,目标函数中的this还指向thisArg
				let thisArgSelf = this instanceof Bound ? this : thisArg;
				self.apply(thisArgSelf,[...list,...arg2])
			}
			// 原型继承
			// Object.create 用来创建以某一个对象作为原型的对象的
			Bound.prototype = Object.create(self.prototype);
			Bound.prototype.constructor = self;
			// 返回的新函数
			return Bound	
		}
		/**this打印的新函数为
		ƒ func(...arg){
			console.log(this);//this指向{a:1}
			console.log(arg)
		}
		*/
		
		function fun(...arg){
			console.log(this);
			console.log(arg);				
		}
		/**控制台打印如下
		{b: 2}
		 (6) [99, 9, 33, 3, 4, 2]
			 -------------------
		 {b: 3}
		 (5) [99, 3, 22, 9, 3]
		*/
		
		//this指向b,返回的新函数为fun1,需要执行这个函数
		let fun1 = fun.bind({b:2},99,9,33);
		let fun2 = fun.customeBind2({b:3},99,3,22);
		fun1(3,4,2);
		console.log('-------------------')
		fun2(9,3);		

分析结束,参考资料《JavaScript高级程序设计》

猜你喜欢

转载自blog.csdn.net/weixin_41762742/article/details/84063659