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的更多相关文章

  1. JavaScript权威设计--JavaScript函数(简要学习笔记十一)

    1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...

  2. JavaScript权威设计--JavaScript函数(简要学习笔记十)

    1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"lik ...

  3. javascript笔记:javascript的关键所在---作用域链

    javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...

  4. JavaScript强化教程——JavaScript 总结

    本教程中我们向您讲授了如何向 html 页面添加 JavaScript,使得网站的动态性和交互性更强. 你已经学习了如何创建对事件的响应,验证表单,以及如何根据不同的情况运行不同的脚本. 你也学到了如 ...

  5. JavaScript学习13 JavaScript中的继承

    JavaScript学习13 JavaScript中的继承 继承第一种方式:对象冒充 <script type="text/javascript"> //继承第一种方式 ...

  6. Javascript学习2 - Javascript中的表达式和运算符

    原文:Javascript学习2 - Javascript中的表达式和运算符 Javascript中的运算符与C/C++中的运算符相似,但有几处不同的地方,相对于C/C++,也增加了几个不同的运算符, ...

  7. Javascript学习1 - Javascript中的类型对象

    原文:Javascript学习1 - Javascript中的类型对象 1.1关于Numbers对象. 常用的方法:number.toString() 不用具体介绍,把数字转换为字符串,相应的还有一个 ...

  8. 第一百二十九节,JavaScript,理解JavaScript库

    JavaScript,理解JavaScript库 学习要点: 1.项目介绍 2.理解JavaScript库 3.创建基础库 从本章,我们来用之前的基础知识来写一个项目,用以巩固之前所学.那么,每个项目 ...

  9. 使用Javascript/jQuery将javascript对象转换为json格式数据 - 海涛的CSDN博客 - 博客频道 - CSDN.NET

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

随机推荐

  1. 【leetcode】Linked List Cycle

    这个题真是坑死了,只怪自己不好吧.一开始审题,以为是给定一个首尾相连的链表,查看其中是否有循环(原谅我的无知吧!!).然后在那写啊写啊写,还在纠结是局部循环还是前一半和后一半一样这样的循环,blah ...

  2. iOS开发之组件化架构漫谈

    前段时间公司项目打算重构,准确来说应该是按之前的产品逻辑重写一个项目.在重构项目之前涉及到架构选型的问题,我和组里小伙伴一起研究了一下组件化架构,打算将项目重构为组件化架构.当然不是直接拿来照搬,还是 ...

  3. Dynamic CRM 2013学习笔记(五)禁止修改、删除审批通过后的单据

    审批通过后的单据,一般要对其进行控制,不能修改,不能添加,删除等,下面分别介绍下如何实现: 一. 禁止修改: 1. 主表控制,如果页面上审批状态为审批中或审批通过,就把整个页面都disable掉 1: ...

  4. 解决“在多字节的目标代码页中,没有此Unicode字符可以映射到的字符”

    今天在处理Google网站管理员中的500错误时发现这样一些URL: http://www.cnblogs.com/Garnai/tag/3D%3F%96%CA/ http://www.cnblogs ...

  5. Html5 Canvas transform setTransform

    Html5 Canvas transform就是矩阵变换,一种坐标的变形. 坐标变形的三种方式,平移translate, 缩放scale以及旋转rotate都可以通过transform做到. tran ...

  6. ZooKeeper 3.5.0 分布式配置问题

    ZooKeeper 3.5.0 分布式配置好后,执行./zkServer.sh start 命令启动,报如下错误: 2015-07-02 21:06:01,671 [myid:] - INFO [ma ...

  7. Jenkins与.NET项目

    转自: https://blog.dangl.me/categories Continuous Integration RSS Date Post 2016-10-20 Set Up Private ...

  8. HTML Meta标签知多少

    文章已同步至个人Blog:Benjamin - 专注前端开发和用户体验 一.基本属性 标签常常被用来定义HTML文档的元数据或者HTTP协议的指向,这些元数据常用在SEO.HTML Pages or ...

  9. mysql where执行顺序

    where执行顺序是从左往右执行的,在数据量小的时候不用考虑,但数据量多的时候要考虑条件的先后顺序,此时应遵守一个原则:排除越多的条件放在第一个. 在用MySQL查询数据库的时候,连接了很多个过滤条件 ...

  10. hibernate懒加载(转载)

    http://blog.csdn.net/sanjy523892105/article/details/7071139 懒加载详解 懒加载为Hibernate中比较常用的特性之一,下面我们详细来了解下 ...