文末
篇幅有限没有列举更多的前端面试题,小编把整理的前端大厂面试题PDF分享出来,一共有269页
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
到这里可能有同学会问,装饰器能加参数吗,比如,我们需要通过参数来判断装饰器需不需要生效,小伙子,灵活点嘛,既然只要后面跟着的是一个函数,那么我们把函数作为返回值,不就可以接收参数了,只要能接收参数,那么里面自然就可以加逻辑,加判断,具体例子如下:
function UserConfig(params: string) {
return function(constructor: any) {
constructor.prototype.name = () => {
console.log(params);
};
};
}
@UserConfig(“oliver”)
class User {
constructor() {
console.log(“你好”);
}
}
const user = new User();
(user as any).name();
到这里,相信各位小伙伴对装饰器有一定了解了吧,现在我们来看一个复杂一点的例子
// 定义一个接口,约束类
interface UserInterface {
name: string;
}
// 定义一个装饰器
function UserConfig<T extends new (…arg: any[]) => any>(constructor: T) {
return class extends constructor {
name = “lilei”;
};
}
// 定义类并使用装饰器
@UserConfig
class User implements UserInterface {
name: string;
constructor(name: string) {
this.name = name;
}
}
const user = new User(“oliver”);
console.log(user.name);
解释一下这段代码:
1)最上面1-4行,定义了一个接口;
2)6-11行,定义了一个装饰器,它的类型比较奇怪,是一个泛型,泛型T,继承了一个new (…arg: any[]) => any这个东西,然后,就是它有一个参数,参数的类型也是泛型T,这个装饰器函数返回了一个类,并且这个类继承了我们的传入的构造函数,这也就是一旦使用我们的装饰器去装饰了某个类,那么这个类上面所有的属性,方法都会被继承,到这里应该没什么问题吧,并在在这个装饰器内部,将其name属性的值改写为了lilei;
那么这里的难点就剩下:new (…arg: any[]) => any,这个是啥,通过关键字new,我们知道这是一个构造函数,并且后面这个也应该是一个函数,…arg: any[]这其实是一个参数的简写,代表着这个构造函数接收任意多的参数,之后这些参数被转成了数组的形式,并且因为我们不知道这个数组的每一项究竟是什么,因此这个数组的类型就是由any组成的数组;
综合的说,new (…arg: any[]) => any,这段代码就是它的类型是一个构造函数,这个构造函数的参数是任意多且任意类型,并且返回值也是任意类型;
3)14行,使用了装饰器
4)15-20行,定义了一个类,它接受接口UserInterface的约束,并且它有一个属性,属性的key是name,值是实例化的时候传入的;