[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& ...
随机推荐
- sqlplus启动后的环境SQLPATH的设置
sqlplus启动时会查找和加载的两个文件login.sql和glogin.sql.其中glogin.sql文件默认存放在$ORACLE_HOME/sqlplus/admin目录下,login.sql ...
- (转载)Autodesk面试技术题解答
Autodesk面试技术题解答 By SmartPtr(http://www.cppblog.com/SmartPtr/) 近一年以来,AUTODESK的面试题在网上是闹的沸沸扬扬, ...
- 在ASP.NET 5中显示错误信息
在 ASP.NET 5 中如果不进行显示错误信息的相关配置,在发生错误时,在浏览器中只能看到空白页面. 显示错误信息的配置方法如下: 1)在 project.json 中添加对 Microsoft.A ...
- Heroku空项目 Git本地Push代码错误 以及 Heroku Web启动错误
在Eclipse下建了一个"Blank Heroku App", 然后将自己写好的JS Web练习代码直接复制放到了这个空项目下, 由于Eclipse下的git工具不太会用, 导致 ...
- Nutz Dao实体中索引注解的使用(@TableIndexes@Index)
Nutz是一组轻便小型的框架的集合, 各个部分可以被独立使用,把SSH的精华封装在一个1M左右的jar包中,Nutz不对其他任何第三方库产生依赖,如果不考虑数据库链接和日志的话,创建完美的Web应用只 ...
- ASP.NET MVC中三方登录: 微软、谷歌、Office365
创建一个MVC的工程,在Startup.Auth.cs文件中,我们能看到这样的一些代码: 这其实是微软已经帮我们实现好的三方登录的接口,我们只需要创建相应的开发者账号,并在其中配置好跟我们应用程序相关 ...
- Windows下安装Ruby
Ruby是一门用了就会喜欢的语言,在Ruby的社区里面,只要你觉得用的不习惯,这就是BUG. 下载 登录官方网址, 下载后,直接无脑下一步安装就行. 中间直接勾选add to PATH,可以自动添加到 ...
- atitit.spring3 mvc url配置最佳实践
atitit.spring3 mvc url配置最佳实践 1. Url-pattern bp 1 2. 通用星号url pattern的问题 1 3. Other code 1 4. 参考 2 1. ...
- 日常开发中常见的HTTP协议的状态码
301Moved Permanently请求的网页已永久移动到新位置.服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将申请人转到新位置.您应使用此代码告诉 Googlebot 某个 ...
- android: 后台执行的定时任务
Android 中的定时任务一般有两种实现方式,一种是使用 Java API 里提供的 Timer 类, 一种是使用 Android 的 Alarm 机制.这两种方式在多数情况下都能实现类似的效果,但 ...