目录前言1. call1.1 语法1.2 流程图1.3 代码实现2. apply2.1 语法2.2 流程图2.3 代码实现3. bind3.1 语法3.2 流程图3.3 代码实现4.
在javascript中,经常会通过call / apply / bind 函数来改变this的指向,详情可看一文带你了解this指向,今天我们来研究下这三个函数的实现。
call()函数是什么?
call()
方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。也就是说call()
改变了this指向并执行了函数。
func.call(thisArg, arg1, arg2, ...)
// thisArg为在 func 函数运行时使用的 this 值
// arg1, arg2等为指定的参数列表
// 其返回值为调用有指定 this 值和参数的函数的结果
一般来说,我们要模拟实现call
,可以分为以下几个步骤:
以下就是call()
方法实现的流程图:
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;
};
apply()函数是什么?
apply()
方法调用一个具有给定 this 值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。同call()
的功能,改变this指向的同时执行了函数。
func.apply(thisArg, [argsArray]);
// thisArg为在 func 函数运行时使用的 this 值
// arg1, arg2等为指定的参数列表
// 其返回值为调用有指定 this 值和参数的函数的结果
apply()
方法实现的流程基本与call
的实现流程没有太多差异,只需要对函数参数数组进行判断展开即可。
以下是apply()
函数的流程图:
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;
};
?bind() 函数是什么?
bind()
方法创建一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
func.bind(thisArg[, arg1[, arg2[, ...]]])
// thisArg 为调用绑定函数时作为 this 参数传递给目标函数的值, 如果使用 new 运算符构造绑定函数,忽略该值
// arg1, arg2为当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
// 其返回值为一个原函数的拷贝,并拥有指定的 this 值和初始参数
想要实现bind
函数,即需实现两个特点:一为返回一个函数;二为可以传入参数。
所以我们可从以下几点入手:
话不多说,下面就是bind
函数的流程图:
Function.prototype.bind = function (thisArg, ...argsArray) {
if (typeof this !== "function") {
throw new TypeError(
"Function.prototype.bind was called on which is not a function"
);
}
if (thisArg === undefined || thisArg === null) {
thisArg = window;
} else {
thisArg = Object(thisArg);
}
const func = this;
const bound = function (...boundArgsArray) {
let isNew = false;
// 如果 func 不是构造器,直接使用 instanceof 将出错,所以需要用 try...catch 包裹
try {
isNew = this instanceof func;
} catch (error) {}
return func.apply(isNew ? this : thisArg, argsArray.concat(boundArgsArray));
};
const Empty = function () {};
Empty.prototype = this.prototype;
bound.prototype = new Empty();
return bound;
};
this
绑定,但 call、apply 函数在改变this指向的同时还会执行函数;而 bind 函数在改变this后返回一个全新的绑定函数。this
被永久绑定;call 与 apply 只适用于当前调用,一次调用后就结束。到此这篇关于一文了解JavaScript中call/apply/bind的使用的文章就介绍到这了,更多相关JavaScript call,apply,bind内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: 一文了解JavaScript中call/apply/bind的使用
本文链接: https://www.lsjlt.com/news/165096.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0