前言

在前端面试中,​​this​​​指向、​​闭包​​​理解与应用、​​原型 Prototype​​等知识点都是经常考察的。那有没有面试题会一次性涉及到这三块儿呢?当然是有的!

​手撕一个bind函数​​就是这样一道经典的面试题!

原生bind函数

​bind() ​​​ 方法创建一个新的函数,在 ​​bind()​​​ 被调用时,这个新函数的 ​​this​​​ 被指定为 ​​bind()​​ 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。


引自MDN


举个栗子????:

// 创建Person类
class Person {
// 定义私有属性 name/age
private name: string;
private age: number;

// 构造函数,初始化时指定name、age的值
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

// 定义printInfo方法,输出信息
printInfo(sex: string) {
console.log(this.name, this.age, sex);
}
}

// 实例化类,获取对象
const p = new Person("Jack", 12);

// 调用printInfo方法
p.printInfo("男"); // Jack 12 男

// 使用bind更改this指向,同时传入参数,返回一个新函数
const printInfo = p.printInfo.bind({ name: "rose", age: 11 }, "女");
// 调用函数
printInfo(); // rose 11 女

梳理一下bind函数的特点:

  1. bind调用完成,返回的是一个新函数;
  2. bind调用时,传入的第一个参数是新的this对象,后续其他参数作为了返回的新函数调用时的参数值

通过​​prototype​​自定义bind函数的实现

Up Code ~ 上代码 ~

/**
* @description 自定义bind方法实现
* @param context any 传入的this对象
* @param bindArgs any[] 传入的参数
*/
// @ts-ignore
Function.prototype.myBind = function (context: any, ...bindArgs: any[]) {
// 原函数的this
// @ts-ignore
const self: any = this;

// 返回一个新函数 - 返回的新函数也是可以继续传递参数的
return function (...args: any[]) {
// 最终的参数
const finalArgs = bindArgs.concat(args);

// 返回原函数的执行结果
return self.apply(context, finalArgs);
};
};


这里一定要注意,.myBind = function () {}位置,不能使用箭头函数,因为一旦使用箭头函数,this指向就确定了,self变量就不能再指向调用myBind的函数了


功能测试:

// @ts-ignore
const printInfo2 = p.printInfo.myBind({ name: "rose", age: 11 }, "女");
printInfo2(); // rose 11 女


相当完美~


结语

手撕一个bind函数这道面试题,考察的知识点还是非常多的,​​this​​​指向问题、​​prototype​​​原型问题、ES6函数剩余参数、​​闭包​​等等,是一道综合性较高的面试题。

以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得​​点赞​​​、​​收藏​​呀,关注胡哥有话说,学习前端不迷路,欢迎多多留言交流...