[Javascript] Decorators in JavaScript
First, what is 'High Order function', basic just a function, inside the function return another fuction.
// High order fucntion function fn() { return function(){ } }
For example:
function compose(a, b) { return function(c){ return a(b(c)); } } function addTwo(val){ return val + 2; } function tiemsTwo(val){ return val * 2; } const val = compose(addTwo, tiemsTwo)(50); console.info(val); // 102
Decorators is a subset of high order fucntion:
function fluent(fn){ return function(...args){ fn.apply(this, args); return this; } } function Person(){} Person.prototype.setName = fluent(function(firstName, lastName){ this.firstName = firstName; this.lastName = lastName; }) Person.prototype.getName = fluent(function(){ console.log(this.firstName + ' ' + this.lastName); }) var p = new Person(); console.log( p.setName('John', 'Kent').getName());
In this code, fluent actually decorate Person class, make it chainable.
But In ES6:
class Person { setName(f, l) { this.firstName = f; this.lastName = l; } getName() { console.log(this.firstName, this.lastName); } }
We have no way to wrap setName and getName fucntion in fluent(). So that's way decorator comes in.
To use decorator to descorate a function in class:
function decorate(target, keys, descriptor){ var fn = descriptor.value; // Overwrite the value, which in this case is function descriptor.value = function(...args){ fn.apply(target, args); return target; } } class Person { @decorate setName(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } @decorate getName(){ console.log(this.firstName, this.lastName); } } const p = new Person(); console.log(p.setName("Wan", "Zhentian").getName());
And it would be nice to reuse the fluent function:
function fluent(fn){ return function(...args){ fn.apply(this, args); return this; } }
So we can do:
function fluent(fn){ return function(...args){ fn.apply(this, args); return this; } } function decorateWith(fn){ return (target, keys, descriptor) => { // fn here refers to setName or getName // fn should be call with in target context, which means Person{} // the second argument in call() is function to be passed into fluent() function
descriptor.value = fn.call(target, descriptor.value); } } class Person { @decorateWith(fluent) setName(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } @decorateWith(fluent) getName(){ console.log(this.firstName, this.lastName); } } const p = new Person(); console.log(p.setName("Wan", "Zhentian").getName());
[Note]: call(context, arguement, arguement, ....); here arguement is sinlge value
apply(context, arguements): here arguements is array
分类:
Javascript
, TypeScript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2015-06-14 [Ionic] Ionic Quickstart for Windows
2013-06-14 【PHP CMS系统】 新闻管理系统 2
2013-06-14 【PHP CMS系统】-- 新闻管理系统 1