JavaScript中call、apply、bind如何巧妙运用,实现函数调用与上下文绑定?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1317个文字,预计阅读时间需要6分钟。
目录前言
1.call
1.1 语法 1.2 流程图 1.3 代码实现2.apply
2.1 语法 2.2 流程图 2.3 代码实现3.bind
3.1 语法 3.2 流程图 3.3 代码实现4.全文总结
call、apply与bind的区别前言在JavaScript中,`call`、`apply`和`bind`是三个常用的函数绑定方法,它们可以将函数绑定到对象,从而改变`this`的指向。以下是这三个方法的详细解析。1. call 1.1 语法 function.call(thisValue, arg1, arg2, ...) 1.2 流程图 流程图 1.3 代码实现 javascript // 代码实现
2. apply 2.1 语法 function.apply(thisValue, [argsArray]) 2.2 流程图 流程图 2.3 代码实现 javascript // 代码实现
3. bind 3.1 语法 function.bind(thisValue, arg1, arg2, ...) 3.2 流程图 流程图 3.3 代码实现 javascript // 代码实现
4. 全文总结 call、apply与bind的区别 在JavaScript中,`call`、`apply`和`bind`都可以改变函数的`this`指向,但它们之间有一些区别:
- `call`和`apply`立即执行函数调用,而`bind`返回一个新的函数,该函数在稍后执行。 - `call`和`apply`可以传入任意数量的参数,而`bind`只能传入参数的列表或单个参数。 - `bind`返回的函数可以进行额外的调用或链式调用,而`call`和`apply`返回的函数不能。
前言 在JavaScript中,函数绑定方法`call`、`apply`和`bind`是强大的工具,可以帮助开发者更好地控制函数的执行环境和`this`的指向。通过理解这些方法的语法和流程,可以更灵活地编写代码。
目录
- 前言
- 1. call
- 1.1 语法
- 1.2 流程图
- 1.3 代码实现
- 2. apply
- 2.1 语法
- 2.2 流程图
- 2.3 代码实现
- 3. bind
- 3.1 语法
- 3.2 流程图
- 3.3 代码实现
- 4.全文总结
- call、apply与bind有什么区别?
前言
在JavaScript中,经常会通过call / apply / bind 函数来改变this的指向,详情可看一文带你了解this指向,今天我们来研究下这三个函数的实现。
1. call
call()函数是什么?
call()方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。也就是说call()改变了this指向并执行了函数。
1.1 语法
func.call(thisArg, arg1, arg2, ...) // thisArg为在 func 函数运行时使用的 this 值 // arg1, arg2等为指定的参数列表 // 其返回值为调用有指定 this 值和参数的函数的结果
1.2 流程图
一般来说,我们要模拟实现call,可以分为以下几个步骤:
- 将函数设置为对象的属性, 当对象为null或undefined, 设为window对象
- 取出函数执行所需参数,执行该函数
- 如果函数存在返回值,在返回后删除该函数
以下就是call()方法实现的流程图:
1.3 代码实现
Function.prototype.call = function (thisArg, ...argsArray) { if (typeof this !== "function") { throw new TypeError( "Function.prototype.call was called on which is not a function" ); } if (thisArg === undefined || thisArg === null) { thisArg = window; } else { thisArg = Object(thisArg); } // 将 func 放入 thisArg 内,这样在调用 thisArg[func] 时 this 自然就指向了 thisArg const func = Symbol("func"); thisArg[func] = this; let result; if (argsArray.length) { result = thisArg[func](...argsArray); } else { result = thisArg[func](); } delete thisArg[func]; return result; };
2. apply
apply()函数是什么?
apply()方法调用一个具有给定 this 值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。同call()的功能,改变this指向的同时执行了函数。
2.1 语法
func.apply(thisArg, [argsArray]); // thisArg为在 func 函数运行时使用的 this 值 // arg1, arg2等为指定的参数列表 // 其返回值为调用有指定 this 值和参数的函数的结果
2.2 流程图
apply()方法实现的流程基本与call的实现流程没有太多差异,只需要对函数参数数组进行判断展开即可。
以下是apply()函数的流程图:
2.3 代码实现
Function.prototype.apply = function (thisArg, argsArray) { if (typeof this !== "function") { throw new TypeError( "Function.prototype.apply was called on which is not a function" ); } if (thisArg === undefined || thisArg === null) { thisArg = window; } else { thisArg = Object(thisArg); } // 将 func 放入 thisArg 内,这样在调用 thisArg[func] 时 this 自然就指向了 thisArg const func = Symbol("func"); thisArg[func] = this; let result; if (argsArray && typeof argsArray === "object" && "length" in argsArray) { // 此处使用 Array.from 包裹让其支持形如 { length: 1, 0: 1 } 这样的类数组对象,直接对 argsArray 展开将会执行出错 result = thisArg[func](...Array.from(argsArray)); } else if (argsArray === undefined || argsArray === null) { result = thisArg[func](); } else { throw new TypeError("CreateListFromArrayLike called on non-object"); } delete thisArg[func]; return result; };
3. bind
本文共计1317个文字,预计阅读时间需要6分钟。
目录前言
1.call
1.1 语法 1.2 流程图 1.3 代码实现2.apply
2.1 语法 2.2 流程图 2.3 代码实现3.bind
3.1 语法 3.2 流程图 3.3 代码实现4.全文总结
call、apply与bind的区别前言在JavaScript中,`call`、`apply`和`bind`是三个常用的函数绑定方法,它们可以将函数绑定到对象,从而改变`this`的指向。以下是这三个方法的详细解析。1. call 1.1 语法 function.call(thisValue, arg1, arg2, ...) 1.2 流程图 流程图 1.3 代码实现 javascript // 代码实现
2. apply 2.1 语法 function.apply(thisValue, [argsArray]) 2.2 流程图 流程图 2.3 代码实现 javascript // 代码实现
3. bind 3.1 语法 function.bind(thisValue, arg1, arg2, ...) 3.2 流程图 流程图 3.3 代码实现 javascript // 代码实现
4. 全文总结 call、apply与bind的区别 在JavaScript中,`call`、`apply`和`bind`都可以改变函数的`this`指向,但它们之间有一些区别:
- `call`和`apply`立即执行函数调用,而`bind`返回一个新的函数,该函数在稍后执行。 - `call`和`apply`可以传入任意数量的参数,而`bind`只能传入参数的列表或单个参数。 - `bind`返回的函数可以进行额外的调用或链式调用,而`call`和`apply`返回的函数不能。
前言 在JavaScript中,函数绑定方法`call`、`apply`和`bind`是强大的工具,可以帮助开发者更好地控制函数的执行环境和`this`的指向。通过理解这些方法的语法和流程,可以更灵活地编写代码。
目录
- 前言
- 1. call
- 1.1 语法
- 1.2 流程图
- 1.3 代码实现
- 2. apply
- 2.1 语法
- 2.2 流程图
- 2.3 代码实现
- 3. bind
- 3.1 语法
- 3.2 流程图
- 3.3 代码实现
- 4.全文总结
- call、apply与bind有什么区别?
前言
在JavaScript中,经常会通过call / apply / bind 函数来改变this的指向,详情可看一文带你了解this指向,今天我们来研究下这三个函数的实现。
1. call
call()函数是什么?
call()方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。也就是说call()改变了this指向并执行了函数。
1.1 语法
func.call(thisArg, arg1, arg2, ...) // thisArg为在 func 函数运行时使用的 this 值 // arg1, arg2等为指定的参数列表 // 其返回值为调用有指定 this 值和参数的函数的结果
1.2 流程图
一般来说,我们要模拟实现call,可以分为以下几个步骤:
- 将函数设置为对象的属性, 当对象为null或undefined, 设为window对象
- 取出函数执行所需参数,执行该函数
- 如果函数存在返回值,在返回后删除该函数
以下就是call()方法实现的流程图:
1.3 代码实现
Function.prototype.call = function (thisArg, ...argsArray) { if (typeof this !== "function") { throw new TypeError( "Function.prototype.call was called on which is not a function" ); } if (thisArg === undefined || thisArg === null) { thisArg = window; } else { thisArg = Object(thisArg); } // 将 func 放入 thisArg 内,这样在调用 thisArg[func] 时 this 自然就指向了 thisArg const func = Symbol("func"); thisArg[func] = this; let result; if (argsArray.length) { result = thisArg[func](...argsArray); } else { result = thisArg[func](); } delete thisArg[func]; return result; };
2. apply
apply()函数是什么?
apply()方法调用一个具有给定 this 值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。同call()的功能,改变this指向的同时执行了函数。
2.1 语法
func.apply(thisArg, [argsArray]); // thisArg为在 func 函数运行时使用的 this 值 // arg1, arg2等为指定的参数列表 // 其返回值为调用有指定 this 值和参数的函数的结果
2.2 流程图
apply()方法实现的流程基本与call的实现流程没有太多差异,只需要对函数参数数组进行判断展开即可。
以下是apply()函数的流程图:
2.3 代码实现
Function.prototype.apply = function (thisArg, argsArray) { if (typeof this !== "function") { throw new TypeError( "Function.prototype.apply was called on which is not a function" ); } if (thisArg === undefined || thisArg === null) { thisArg = window; } else { thisArg = Object(thisArg); } // 将 func 放入 thisArg 内,这样在调用 thisArg[func] 时 this 自然就指向了 thisArg const func = Symbol("func"); thisArg[func] = this; let result; if (argsArray && typeof argsArray === "object" && "length" in argsArray) { // 此处使用 Array.from 包裹让其支持形如 { length: 1, 0: 1 } 这样的类数组对象,直接对 argsArray 展开将会执行出错 result = thisArg[func](...Array.from(argsArray)); } else if (argsArray === undefined || argsArray === null) { result = thisArg[func](); } else { throw new TypeError("CreateListFromArrayLike called on non-object"); } delete thisArg[func]; return result; };

