[Javascript] Decorators in JavaScript
JavaScript in
2023-09-14 08:59:19 时间
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 基础_JavaScript高级编程
- html 滚动条 scrolltop scrollheight,浅谈JavaScript中scrollTop、scrollHeight、offsetTop、offsetHeight…
- 【说站】javascript工厂模式是什么
- JavaScript 数据类型与运算符(下)
- 内存数据库 mysql-mysql in memory_In-Memory:内存数据库
- MySQL查询优化:从IN中获取更高性能(mysql查询优化in)
- 使用 JavaScript 调用 Linux 命令的实现方法(js调用linux命令)
- 查询解锁Oracle多条件In查询的机密(oracle多条件in)
- 如何在MySQL中代替IN关键字(mysql中代替in)
- MySQL中使用IN函数的查询限制是什么(mysql中in的限制)
- MySQL中IN操作符的使用限制 最多能使用多少个(mysql中in的个数)
- MySQL中使用IN操作会影响性能吗(mysql中in性能)
- 深入剖析MySQL中IN和等于操作的差异与应用(mysql中in和等于)
- MySQL表中使用IN命令优化索引,提高查询效率(mysql中in命中索引)
- MySQL中的IN子句如何利用索引实现高效查询(mysql中in使用索引)
- 的区别Oracle中IN与的异同探究(oracle中in和=)
- 从Oracle到NO IN数据库迁移指南(oracle no in)
- in用Oracle中Like和In实现模糊查询(oracle like和)
- javascript下给元素添加事件的方法与代码
- JavaScript入门教程(3)js面向对象
- javascript表单验证常见正则
- javascript动态改变onclick事件触发函数代码
- Javascript异步加载详解(浏览器在javascript的加载方式)
- JavaScript高级程序设计阅读笔记(十六)javascript检测浏览器和操作系统-detect.js
- 浅析JavaScript中的同名标识符优先级
- javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
- 浅析javascript中function的length属性
- javascript中parseInt()函数的定义和用法分析