JavaScript装饰器函数(Decorator)实例详解


Posted in Javascript onMarch 30, 2017

本文实例讲述了JavaScript装饰器函数(Decorator)。分享给大家供大家参考,具体如下:

装饰器函数(Decorator)用于给对象在运行期间动态的增加某个功能,职责等。相较通过继承的方式来扩充对象的功能,装饰器显得更加灵活,首先,我们可以动态给对象选定某个装饰器,而不用hardcore继承对象来实现某个功能点。其次:继承的方式可能会导致子类繁多,仅仅为了增加某一个单一的功能点,显得有些多余了。

下面给出几个常用的装饰器函数示例,相关代码请查看github。

1 动态添加onload监听函数

function addLoadEvent(fn) {
  var oldEvent = window.onload;
  if(typeof window.onload != 'function') {
    window.onload = fn;
  }else {
    window.onload = function() {
      oldEvent();
      fn();
    };
  }
}
function fn1() {
  console.log('onloadFunc 1');
}
function fn2() {
  console.log('onloadFunc 2');
}
function fn3() {
  console.log('onloadFunc 3');
}
addLoadEvent(fn1);
addLoadEvent(fn2);
addLoadEvent(fn3);

JavaScript装饰器函数(Decorator)实例详解

2 前置执行函数和后置执行函数

Function.prototype.before = function(beforfunc) {
  var self = this;
  var outerArgs = Array.prototype.slice.call(arguments, 1);
  return function() {
    var innerArgs = Array.prototype.slice.call(arguments);
    beforfunc.apply(this, innerArgs);
    self.apply(this, outerArgs);
  };
};
Function.prototype.after = function(afterfunc) {
  var self = this;
  var outerArgs = Array.prototype.slice.call(arguments, 1);
  return function() {
    var innerArgs = Array.prototype.slice.call(arguments);
    self.apply(this, outerArgs);
    afterfunc.apply(this, innerArgs);
  };
};
var func = function(name){
  console.log('I am ' + name);
};
var beforefunc = function(age){
  console.log('I am ' + age + ' years old');
};
var afterfunc = function(gender){
  console.log('I am a ' + gender);
};
var beforeFunc = func.before(beforefunc, 'Andy');
var afterFunc = func.after(afterfunc, 'Andy');
beforeFunc('12');
afterFunc('boy');

执行结果,控制台打印如下:

I am 12 years old
I am Andy
I am Andy
I am a boy

3 函数执行时间计算

function log(func){
  return function(...args){
    const start = Date.now();
    let result = func(...args);
    const used = Date.now() - start;
    console.log(`call ${func.name} (${args}) used ${used} ms.`);
    return result;
  };
}
function calculate(times){
  let sum = 0;
  let i = 1;
  while(i < times){
    sum += i;
    i++;
  }
  return sum;
}
runCalculate = log(calculate);
let result = runCalculate(100000);
console.log(result);

注:这里我使用了ES2015(ES6)语法,如果你感兴趣可以查看前面关于ES6的相关内容。

JavaScript装饰器函数(Decorator)实例详解

当然,装饰器函数不仅仅这些用法。天猫使用的Nodejs框架Koa就基于装饰器函数及ES2015的Generator。希望这篇文章能起到抛砖引玉的作用,使你编写更优雅的JS代码。

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
把textarea中字符串里含有的回车换行替换成&amp;lt;br&amp;gt;的javascript代码
Apr 20 Javascript
JavaScript中判断函数是new还是()调用的区别说明
Apr 07 Javascript
jQuery each函数源码分析
May 25 Javascript
JS实现pasteHTML兼容ie,firefox,chrome的方法
Jun 22 Javascript
JavaScript实现汉字转换为拼音的库文件示例
Dec 22 Javascript
JavaScript仿聊天室聊天记录
Dec 27 Javascript
Node.js中的require.resolve方法使用简介
Apr 23 Javascript
js使用generator函数同步执行ajax任务
Sep 05 Javascript
基于js中style.width与offsetWidth的区别(详解)
Nov 12 Javascript
js推箱子小游戏步骤代码解析
Jan 10 Javascript
原生JavaScript实现remove()和recover()功能示例
Jul 24 Javascript
vue自动添加浏览器兼容前后缀操作
Aug 13 Javascript
Angular.JS去掉访问路径URL中的#号详解
Mar 30 #Javascript
详解Angular.js数据绑定时自动转义html标签及内容
Mar 30 #Javascript
JavaScript观察者模式(publish/subscribe)原理与实现方法
Mar 30 #Javascript
Angular.js去除页面中显示的空行方法示例
Mar 30 #Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
Mar 30 #Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
Mar 30 #Javascript
JavaScript mixin实现多继承的方法详解
Mar 30 #Javascript
You might like
php简单统计字符串单词数量的方法
2015/06/19 PHP
Symfony2联合查询实现方法
2016/03/18 PHP
thinkPHP中验证码的简单实现方法
2016/12/05 PHP
php快速导入大量数据的实例方法
2019/09/23 PHP
使用tp框架和SQL语句查询数据表中的某字段包含某值
2019/10/18 PHP
Javascript 获取链接(url)参数的方法
2009/02/15 Javascript
xml和web特殊字符
2009/04/28 Javascript
javascript中用星号表示预录入内容的实现代码
2011/01/08 Javascript
使用js显示当前时间示例
2014/03/02 Javascript
jquery+正则实现统一的表单验证
2015/09/20 Javascript
javascript滚轮控制模拟滚动条
2016/10/19 Javascript
详解Javascript数据类型的转换规则
2016/12/12 Javascript
laydate.js日期时间选择插件
2017/01/04 Javascript
Vue 短信验证码组件开发详解
2017/02/14 Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
2017/08/15 Javascript
vue 2.0 购物车小球抛物线的示例代码
2018/02/01 Javascript
jQuery使用$.extend(true,object1, object2);实现深拷贝对象的方法分析
2019/03/06 jQuery
JS轮播图的实现方法2
2020/08/25 Javascript
python 图片验证码代码
2008/12/07 Python
Python类定义和类继承详解
2015/05/08 Python
Python实现的最近最少使用算法
2015/07/10 Python
Python爬取网易云音乐上评论火爆的歌曲
2017/01/19 Python
Python实现二叉树前序、中序、后序及层次遍历示例代码
2019/05/18 Python
Ubuntu18.04中Python2.7与Python3.6环境切换
2019/06/14 Python
Pytorch之contiguous的用法
2019/12/31 Python
使用CSS3中的calc()属性来以算式表达尺寸数值
2016/06/06 HTML / CSS
用CSS3的box-reflect来制作倒影效果
2016/11/15 HTML / CSS
Nike加拿大官网:Nike.com (CA)
2019/04/09 全球购物
农田水利实习自我鉴定
2013/09/19 职场文书
青年教师典范事迹材料
2014/01/31 职场文书
贷款担保申请书
2014/05/20 职场文书
反对四风问题自我剖析材料
2014/09/29 职场文书
西湖英语导游词
2015/02/06 职场文书
和领导吃饭祝酒词
2015/08/11 职场文书
Django给表单添加honeypot验证增加安全性
2021/05/06 Python
深入解析Apache Hudi内核文件标记机制
2022/03/31 Servers