今天来实作一个 Decorator 的例子,当我们在画面上有一个按钮,想要透过点击该按钮触发 showMessage()
显示 Printer
实例里面的 message
,但因为是 event listener 的关系,这样点击会是 console
undifined
的,因为 this
是指向 event,而非 class。在 JavaScript 我们会写成 p.showMessage.bind(p)
确保 this
的指向,但也可以透过 Decorator 来实现这件事。
function Autobind(target: any, methodName: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
const adjDescriptor: PropertyDescriptor = {
configurable: true,
enumerable: false,
get() {
const boundFn = originalMethod.bind(this);
return boundFn;
}
};
return adjDescriptor;
}
class Printer {
message = 'This works!';
@Autobind
showMessage() {
console.log(this.message);
}
}
const p = new Printer();
p.showMessage();
const button = document.querySelector('button')!;
button.addEventListener('click', p.showMessage);
透过 Method Decorator,我们可以从 descriptor 拿到 value,它会拿到装饰的 function,这时候我们定义一个 PropertyDescriptor 型别的物件,从中可以设定他的物件里面的值,并增加一个 getter
,在里面使用 bind
方法绑住 this
,其实跟原生的 JavaScript 的方法一样,这边是学到了另外一种做法,写了一次之後不管在哪边呼叫 showMEssage()
都不用再担心 this
的指向了,觉得虽然写了比较多程序码,但是如果写了这一次,就不用担心之後如果有需要用到触发这个 Printer
class 的 showMessage()
来显示 message
时却忘记用 bind
方法还得等执行了之後才能去 debug,或许用 Decorator 保险了许多!
今天的学习笔记到这边,未来若有时间会再回来撰写用 Decorator 来实现验证的功能~谢谢阅读。:)
<<: Day 15 - Ping Sweeping 与 Port Scanning
大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...
在 Google 搜寻公告中,已经将 Https 连线列为重要的网站优化排名之中,拥有 https ...
首先要注意 Ruby 和 Rails 是不一样的东西! Ruby 是一种物件导向的程序语言,而 R...
今天要来介绍 Module,写 Module 的好处在於,可以把程序码分成不同档案来管理,会比较好维...
客户端的属性或属性值无法向IdP认证客户端。例如,提交用户名和员工ID的用户将不会向IdP进行身份验...