[Javascript] Decorators in JavaScript
2016-06-14 03:10
309 查看
First, what is 'High Order function', basic just a function, inside the function return another fuction.
For example:
Decorators is a subset of high order fucntion:
In this code, fluent actually decorate Person class, make it chainable.
But In ES6:
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:
And it would be nice to reuse the fluent function:
So we can do:
[Note]: call(context, arguement, arguement, ....); here arguement is sinlge value
apply(context, arguements): here arguements is array
// 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
相关文章推荐
- seaJS 简要介绍和完整例子
- 排序__js
- 第二章 JavaScript语法·
- 第一章 JavaScript简史
- Javascript基础知识
- JavaScript 实现简单的神经网络算法
- js数组
- Answering Baranovskiy’s JavaScript quiz
- javascript获取一个数组中的最小值
- md5 JavaScript js
- HTML年月日的JS实现
- JavaScript中的一些特殊用法(三)
- Javascript/js兼容各个浏览器的本地图片上传即时预览效果
- JavaScript 函数 encodeURI(), encodeURIComponent()的使用
- JS实现的HashMap功能
- 前端学习_Series2_01.JavaScript_03
- Js 调用 webservice
- JSP九大内置对象的作用和用法总结?
- js获得浏览器的尺寸
- jsp基础