[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] Decorators in JavaScript的更多相关文章
- JavaScript权威设计--JavaScript函数(简要学习笔记十一)
1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...
- JavaScript权威设计--JavaScript函数(简要学习笔记十)
1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"lik ...
- javascript笔记:javascript的关键所在---作用域链
javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...
- JavaScript强化教程——JavaScript 总结
本教程中我们向您讲授了如何向 html 页面添加 JavaScript,使得网站的动态性和交互性更强. 你已经学习了如何创建对事件的响应,验证表单,以及如何根据不同的情况运行不同的脚本. 你也学到了如 ...
- JavaScript学习13 JavaScript中的继承
JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...
- Javascript学习2 - Javascript中的表达式和运算符
原文:Javascript学习2 - Javascript中的表达式和运算符 Javascript中的运算符与C/C++中的运算符相似,但有几处不同的地方,相对于C/C++,也增加了几个不同的运算符, ...
- Javascript学习1 - Javascript中的类型对象
原文:Javascript学习1 - Javascript中的类型对象 1.1关于Numbers对象. 常用的方法:number.toString() 不用具体介绍,把数字转换为字符串,相应的还有一个 ...
- 第一百二十九节,JavaScript,理解JavaScript库
JavaScript,理解JavaScript库 学习要点: 1.项目介绍 2.理解JavaScript库 3.创建基础库 从本章,我们来用之前的基础知识来写一个项目,用以巩固之前所学.那么,每个项目 ...
- 使用Javascript/jQuery将javascript对象转换为json格式数据 - 海涛的CSDN博客 - 博客频道 - CSDN.NET
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
随机推荐
- 学习WCF之——wcf程序的创建
这是我参考的主要资料——wcf学习之旅:http://www.cnblogs.com/artech/archive/2007/02/26/656901.html 首先,如博客上介绍的一样,创建空白的项 ...
- UIPageControl页控制器
一.基本知识 #import "ViewController.h"@interface ViewController ()<UIScrollViewDelegate>{ ...
- haskell中的monad
monad本意是单子.在haskell中,第一个接触的基本都是IO action,通过把IO动作包装起来我们能很方便的与现实世界进行数据交换.但其实monad的用途不止如此,monad还能讲一系列操作 ...
- 互联网上那些excel文件
互联网上那些excel文件 文/玄魂 目录 互联网上那些excel文件 前言 1.1 查找包含指定值的excel文件 1.2 查找邮箱 1.3 查找身份证号 1.4 查找管理人员联系信息 1.5 获 ...
- 转载:SQL Server 2008-建立分区表(Table Partition) 转载
数据库结构和索引的是否合理在很大程度上影响了数据库的性能,但是随着数据库信息负载的增大,对数据库的性能也发生了很大的影响.可能我们的数据库在一开始有着很高的性能,但是随着数据存储量的急速增长—例如订单 ...
- jenkins2 pipeline插件的10个最佳实践
jenkins pipeline的10个最佳实践. 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://github.com/ciandcd ...
- JQuery高性能优化
使用JQuery时,你可以使用多种选择器,选择同一个元素,各种方法之间的性能是不一样的,有时候差异会特别大. 通常比较常用的选择器有以下几个: ID选择器 $("#id") 标签选 ...
- paip.提升性能---mysql 性能 测试以及 参数调整.txt
paip.提升性能---mysql 性能 测试以及 参数调整.txt 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://b ...
- atitit.ajax bp dwr 3.的注解方式配置使用流程总结 VO9o.....
atitit.ajax bp dwr 3.的注解方式配置使用流程总结 VO9o..... 1. 安装配置 1 1.1. 下载 dwr.jar 1M 1 1.2. 配置注解方式..web.xml 1 ...
- paip java.net.SocketException No buffer space available的解决办法及总结
java.net.SocketException No buffer space available的解决办法及总结 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来 ...