返回
手撕新、调用、应用、绑定,然后重新实现一遍
前端
2023-09-16 09:42:10
揭开 JavaScript 函数调用魔术的面纱:深入了解 new、call、apply 和 bind
在 JavaScript 的广阔世界中,new、call、apply 和 bind 这四个函数充当了强大的工具,让你可以灵活地调用函数,从而增强代码的可复用性和可扩展性。
new:创建对象的起点
new 运算符是创建新对象的桥梁。它调用构造函数,为新对象分配内存,并设置其内部属性。构造函数的作用就像一个蓝图,定义对象的属性和行为。
call 和 apply:改变函数的上下文
call 和 apply 允许你改变函数调用的上下文。它们让你可以使用不同的对象作为函数的 this ,就像把函数“借”给其他对象使用一样。
bind:创建预先绑定的函数
bind 不同于 call 和 apply,它并不立即调用函数,而是创建一个新的函数,该函数被绑定到特定的上下文。这个新函数在以后调用时,无论你使用什么对象调用,它都会保持绑定的上下文。
重新实现这些函数:深入了解它们的内部机制
要真正理解这些函数,我们不妨尝试自己重新实现它们:
new
function new(constructor, ...args) {
const obj = {};
Object.setPrototypeOf(obj, constructor.prototype);
const result = constructor.apply(obj, args);
return typeof result === 'object' ? result : obj;
}
call
Function.prototype.call = function(context, ...args) {
context = context || globalThis;
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
};
apply
Function.prototype.apply = function(context, args) {
context = context || globalThis;
context.fn = this;
const result = context.fn(...args);
delete context.fn;
return result;
};
bind
Function.prototype.bind = function(context, ...args) {
const fn = this;
return function(...newArgs) {
return fn.apply(context, [...args, ...newArgs]);
};
};
常见问题解答
-
为什么使用 call 和 apply 而不用 bind?
- call 和 apply 允许你立即调用函数,而 bind 则创建了一个预先绑定的函数,可以在以后调用。
-
new、call、apply 和 bind 之间有什么区别?
- new 创建对象,call 和 apply 改变函数的上下文,bind 创建预先绑定的函数。
-
如何使用 bind 来创建类实例?
- 通过将类构造函数作为 bind 的第一个参数,并传递所需的属性作为额外参数,可以创建类的实例。
-
call、apply 和 bind 如何处理箭头函数?
- 箭头函数没有自己的 this 关键字,因此 call、apply 和 bind 对它们无效。
-
这些函数在现代 JavaScript 中的使用情况是什么?
- 它们仍然在 JavaScript 中广泛使用,特别是在处理复杂的对象和函数调用时。
结论
掌握 new、call、apply 和 bind 等函数,可以极大地增强你的 JavaScript 编程能力。它们提供了一种灵活的方法来调用函数,从而提高代码的可复用性和可维护性。了解这些函数的底层原理,将为你打开创造更强大、更优雅的 JavaScript 程序的大门。