JavaScript中apply,call和bind方法

160 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

call(), apply() 和 bind() 这三个函数的方法,可以用来改变函数中 this 绑定的上下文对象。接下来让我们来一起了解一下它们!


1. apply 和 call

apply()call() 这两个方法都会以指定的 this 值来调用函数(即调用函数时,设置函数中 this 绑定的上下文对象)

1.1) apply

apply() 方法接受两个参数。

  • 第一个参数:我们想要 this 绑定的上下文对象
  • 第二个参数:我们想要传递的参数(以数组类数组对象传入-可以包含任意数量)

通过一个例子,来理解一下:

let a = 1;
let obj = {
	a: 2
}

function sayValue(...args) {
	console.log(this.a, ...args);
}

sayValue.apply(obj, [3, 4]);

在这里插入图片描述

1.2) call

cal() 方法和 apply() 方法的作用一样,只不过传参的形式不同

  • 第一个参数:我们想要 this 绑定的上下文对象
  • 其余参数:逐个传入

通过一个例子,来理解一下:

let a = 1;
let obj = {
	a: 2
}

function sayValue(...args) {
	console.log(this.a, ...args);
}

// 要传给函数的参数要逐个传入参数
sayValue.call(obj, 3, 4);

在这里插入图片描述


2. bind

2.1) bind 介绍

bind() 方法:创建一个新函数,它的 this 为我们想要 this 绑定的上下文对象,也就是传入的对象(即返回一个 this 绑定了传入对象的新函数

  • 第一个参数:我们想要 this 绑定的上下文对象
  • 其余参数:逐个传入

通过一个例子,来理解一下:

let a = 1;
let obj = {
	a: 2
}

function sayValue(...args) {
	console.log(this.a, ...args);
}

let sayObjValue = sayValue.bind(obj, 3, 4);
sayObjValue();

在这里插入图片描述

2.2) 手写 bind

Function.prototype.myBind = function(context) {
	// 调用 myBind 的不是函数,则抛出异常
	if (typeof this !== 'function') {
		throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
	}
	
	const self = this;
	// 去除第一个参数---要绑定的对象,留下实际传入的参数
	const args = [...arguments].slice(1);
	
	// 创建要返回的新函数
	const newFunc = function() {
		// 当 myBind 作为一个构造函数的时候,不用改变this的指向
		const _this = this instanceof newFunc ? this : context;
		// 将传入的参数和返回的函数传入的参数合并
		const newArgs = [...args, ...arguments];
		self.apply(_this, newArgs);
	};
	
	// 当 new 的时候,空对象的原型指向绑定函数的原型
	/*
	  在这里不能直接 newFunc.prototype = this.prototype
	  如果直接 newFunc.prototype = this.prototype
	  newFunc.prototype 和 this.prototype 指向同一个内存空间
	  它们之间的改变就会造成互相影响,这不是我们想要的效果
	*/
	const Fn = function() {};
	Fn.prototype = this.prototype;
	newFunc.prototype = new Fn();
	return newFunc;
}