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 相关文章推荐
js验证模型自我实现的具体方法
Jun 21 Javascript
Js日期选择器并自动加入到输入框中示例代码
Aug 02 Javascript
JS实现点击按钮后框架内载入不同网页的方法
May 05 Javascript
Jquery检验手机号是否符合规则并根据手机号检测结果将提交按钮设为不同状态
Nov 26 Javascript
JS与Ajax Get和Post在使用上的区别实例详解
Jun 08 Javascript
深入理解jQuery.data() 的实现方式
Nov 30 Javascript
详解node Async/Await 更好的异步编程解决方案
May 10 Javascript
记一次webpack3升级webpack4的踩坑经历
Jun 12 Javascript
微信小程序实现收藏与取消收藏切换图片功能
Aug 03 Javascript
vue返回上一页面时回到原先滚动的位置的方法
Dec 20 Javascript
postman自定义函数实现 时间函数的思路详解
Apr 17 Javascript
uniapp实现可以左右滑动导航栏
Oct 21 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
与数据库连接
2006/10/09 PHP
ZF等常用php框架中存在的问题
2008/01/10 PHP
php 数组处理函数extract详解及实例代码
2016/11/23 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
2017/08/31 PHP
PHP 使用二进制保存用户状态的实例
2018/01/29 PHP
浅谈php的TS和NTS的区别
2019/03/13 PHP
屏蔽F1~F12的快捷键的js函数
2010/05/06 Javascript
A标签触发onclick事件而不跳转的多种解决方法
2013/06/27 Javascript
JS按字节截取字符长度实例
2013/11/20 Javascript
jquery插件jquery.confirm弹出确认消息
2015/12/22 Javascript
详解javascript跨浏览器事件处理程序
2016/03/27 Javascript
jQuery实现区域打印功能代码详解
2016/06/17 Javascript
使用nodejs中httpProxy代理时候出现404异常的解决方法
2016/08/15 NodeJs
jQuery Easyui Tabs扩展根据自定义属性打开页签
2016/08/15 Javascript
Javascript中内建函数reduce的应用详解
2016/10/20 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
2017/01/22 Javascript
不得不看之JavaScript构造函数及new运算符
2017/08/21 Javascript
vue获取DOM元素并设置属性的两种实现方法
2017/09/30 Javascript
React SSR样式及SEO的实践
2018/10/22 Javascript
vue+SSM实现验证码功能
2018/12/07 Javascript
Vue使用Clipboard.JS在h5页面中复制内容实例详解
2019/09/03 Javascript
详解如何在Javascript和Sass之间共享变量
2019/11/13 Javascript
JS 数组和对象的深拷贝操作示例
2020/06/06 Javascript
在vue中使用vant TreeSelect分类选择组件操作
2020/11/02 Javascript
python使用urllib模块开发的多线程豆瓣小站mp3下载器
2014/01/16 Python
查看Django和flask版本的方法
2018/05/14 Python
pycharm远程开发项目的实现步骤
2019/01/20 Python
解决python Markdown模块乱码的问题
2019/02/14 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
2019/10/24 Python
基于python实现文件加密功能
2020/01/06 Python
python pillow库的基础使用教程
2021/01/13 Python
通过一张图教会你CSS3倒影的实现
2017/09/26 HTML / CSS
HTML5梦幻之旅——炫丽的流星雨效果实现过程
2013/08/06 HTML / CSS
芭比波朗加拿大官方网站:Bobbi Brown Cosmetics CA
2020/11/05 全球购物
材料加工硕士生求职信
2013/10/10 职场文书
Opencv中cv2.floodFill算法的使用
2021/06/18 Python