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 相关文章推荐
一个多次搜索+多次传值的解决方案
Jan 20 Javascript
jQuery EasyUI API 中文文档 - Pagination分页
Sep 29 Javascript
js 为label标签和div标签赋值的方法
Aug 08 Javascript
JavaScript中使用arguments获得函数传参个数实例
Aug 27 Javascript
jquery实现的判断倒计时是否结束代码
Feb 05 Javascript
jQuery on()方法绑定动态元素的点击事件无响应的解决办法
Jul 07 Javascript
javascript内存分配原理实例分析
Apr 10 Javascript
微信小程序自定义导航隐藏和显示功能
Jun 13 Javascript
微信禁止下拉查看URL的处理方法
Sep 28 Javascript
微信小程序语音同步智能识别的实现案例代码解析
May 29 Javascript
如何在postman测试用例中实现断言过程解析
Jul 09 Javascript
jQuery实现全选按钮
Jan 01 jQuery
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
smarty 原来也不过如此~~呵呵
2006/11/25 PHP
yii2实现分页,带搜索的分页功能示例
2017/01/07 PHP
Javascript 验证上传图片大小[客户端]
2009/08/01 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
jQuery密码强度检测插件passwordStrength用法实例分析
2015/10/30 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
2016/02/29 Javascript
AngularJS ng-change 指令的详解及简单实例
2016/07/30 Javascript
Node.js下自定义错误类型详解
2016/10/17 Javascript
纯JS焦点图特效实例(可一个页面多用)
2016/12/07 Javascript
浅谈react受控组件与非受控组件(小结)
2018/02/09 Javascript
详解SPA中前端路由基本原理与实现方式
2018/09/12 Javascript
vue实现的双向数据绑定操作示例
2018/12/04 Javascript
Vue-CLI3.x 设置反向代理的方法
2018/12/06 Javascript
vue-drawer-layout实现手势滑出菜单栏
2020/11/19 Vue.js
[59:08]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第一局
2016/02/27 DOTA
Python中转换角度为弧度的radians()方法
2015/05/18 Python
Python实现感知器模型、两层神经网络
2017/12/19 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
2018/04/27 Python
python 实现查找文件并输出满足某一条件的数据项方法
2019/06/12 Python
在Tensorflow中实现梯度下降法更新参数值
2020/01/23 Python
Python3.9又更新了:dict内置新功能
2020/02/28 Python
Python实现删除某列中含有空值的行的示例代码
2020/07/20 Python
Python结合Window计划任务监测邮件的示例代码
2020/08/05 Python
Numpy中np.random.rand()和np.random.randn() 用法和区别详解
2020/10/23 Python
python定义具名元组实例操作
2021/02/28 Python
“型”走纽约上东区:Sam Edelman
2017/04/02 全球购物
流行文化收藏品:Sideshow(DC漫画,星球大战,漫威)
2019/03/17 全球购物
Order by的几种用法
2013/06/16 面试题
动态密码技术
2012/10/18 面试题
副总经理岗位职责
2014/03/16 职场文书
小班下学期评语
2014/05/04 职场文书
优秀班主任推荐材料
2014/12/17 职场文书
施工员岗位职责
2015/02/10 职场文书
大学升旗仪式主持词
2015/07/04 职场文书
mysql使用 not int 子查询隐含陷阱
2022/04/12 MySQL
Java服务调用RestTemplate与HttpClient的使用详解
2022/06/21 Java/Android