js 手写实现bind方法
文章目录
在实现bind方法之前,我们知道call、apply和bind是三个重要的函数方法,它们都与函数调用和this关键字有关。本文将讲解它们之间的使用和区别以及bind的实现思路。
一、call、apply、bind
1.1 call方法
call
方法是Function对象原型上的一个方法,它允许你在调用函数的同时显式指定函数的this值,并且可以传递多个参数。
function fn(val) {
console.log(this, val);
}
const person = { name: "John" };
fn.call(person, "Alice");
从上面我们可以看出,this的指向发生了改变,指向了person。
1.2 apply方法
apply方法与call类似,但是它接收的参数是一个数组。
function fn(val) {
console.log(this, val);
}
const person = { name: "John" };
fn.apply(person, ["Alice"]);
1.3 bind方法
bind方法创建一个新的函数,并将指定的对象绑定为新函数的this值。与call和apply不同的是,bind并不会立即调用函数,而是返回一个新的函数,新的函数可以再传值
function fn(...res) {
console.log(this, res);
}
const person = { name: "John" };
fn.bind(person, "Alice")("Bob");
1.4 call、apply、bind区别
- 使用call和apply时,函数会立即执行,而bind返回一个新函数不会立即执行。
- call和apply的主要区别在于参数的传递方式,call是逐个传递,而apply是通过数组传递。
二、手写bind
2.1 普通函数调用情况
//原函数无返回值情况
function fn(...res) {
console.log(this, res); //this:person res:['Alice','Bob']
}
const person = { name: "John" };
console.log(fn.bind(person, "Alice")("Bob")); //undefined
//原函数有返回值情况
function fn(...res) {
console.log(this, res); //this:person res:['Alice','Bob']
return "Hello WOrld";
}
const person = { name: "John" };
console.log(fn.bind(person, "Alice")("Bob")); //Hello WOrld
从上面我们可以看出,若原函数有返回值,则会成为新函数的返回值,否则为undefined
2.2 构造函数调用情况
function fn(...res) {
console.log(this, res); //this:fn res: ['Alice', 'Bob2']
return "Hello World";
}
const person = { name: "John" };
const f = fn.bind(person, "Alice");
console.log(new f("Bob2")); //fn
从上面我们可以看出,使用 new 调用时,this 指向实例对象,返回值也是该实例对象。
2.3 bind手写实现
基于上面的探讨,我们明白bind除了考虑函数的返回值,还得考虑是普通函数调用还是构造函数调用。具体实现代码如下:
Function.prototype.myBind = function (thisArg, ...outerRes) {
if (typeof this !== "function") {
throw new Error("bind只能绑定函数");
}
const originFn = this;
const innerFn = function (...innerRes) {
if (this instanceof innerFn) {
const targe = {};
targe.__proto__ = originFn.prototype;
originFn.apply(targe, outerRes.concat(innerRes));
return targe;
} else {
return originFn.apply(thisArg, outerRes.concat(innerRes));
}
};
return innerFn;
};
function fn(...res) {
console.log(this, res); //this:fn res:['Alice', 'Bob2']
}
const person = { name: "John" };
const f = fn.myBind(person, "Alice");
console.log(new f("Bob2")); //fn
我们面试中常常会遇到手写bind方法这个面试题,上面的代码就可以很好的应对。不过在实际开发中,往往需要考虑更复杂的情况,建议使用现有的bind方法,或者在需要的情况下使用现代的 JavaScript 特性,如箭头函数,以减少手动实现的复杂性。
原文地址:https://blog.csdn.net/weixin_45532665/article/details/136231928
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!