使用babel深入理解es7的decorator
来源:互联网 发布:淘宝账号登陆不了 编辑:程序博客网 时间:2024/05/22 06:49
es7提出了decorator的语法,让我们能写出更优雅更好维护的代码,装饰器的本质是对现有的功能进行包装,可以用来加钩子或者增强功能等,js从语法层面支持这种写法,让我们可以保持代码解耦。
比如我们有一个函数
funciton update() { console.log('update db')}
我们想在执行这个函数时打日志,我们可能会这样改写
funciton update() { log('log') console.log('update db')}
或者用高阶函数装饰update
decoratorUpdate = funciton( ) { log('log') update();}
这样会让我们的代码被业务无关的代码侵入,增加了耦合度。
在es7里我们可以这样写
funciton log(className, propName, descriptor) { var value = descriptor.value; descriptor.value = funciton() { console.log('update db'); value(); }}class Curd{ @log update() { }}
这样我们的代码里,业务相关的代码和无关的代码分离。更加清晰。
下面我们使用babel看一下es7的decorator本质是什么。
1.首先我们安装babel。
npm install babel-loader babal-core babel-preset-es2015 babel-plugin-transform-decorators-legacy
写某个文件夹下新建.babelrc文件。
{ "presets": [ // 把es6转成es5 'babel-preset-es2015' ], // 把装饰器语法转成es5 "plugins": ['transform-decorators-legacy'] }
然后,新建index.js
/* target 类的prototype name 类prototype上的属性 descriptor 描述符*/function readonly(target, name, descriptor) { descriptor.writable = false; return descriptor;}// descriptor为数据描述符function log(target, name, descriptor) { // 保存原来的值 var value = descriptor.value; // 加钩子 descriptor.value = function() { console.log('log'); // 调用原来的值 value(); } return descriptor;}// descriptor为存取描述符function get(target, name, descriptor) { var value = descriptor.get; descriptor.get = function() { console.log('log'); console.log(value()) } return descriptor}function decoratorFactory(type) { switch(type) { case 1: return function(target, name, descriptor) { var value = descriptor.value; descriptor.value = function() { console.log('you will say hello =>'); console.log(value()) } return descriptor; } case 2: return function(target, name, descriptor) { var value = descriptor.value; descriptor.value = function() { console.log('you will say world =>'); console.log(value()) } return descriptor; } }}function classDecorator(className) { className.flag = true; return className;}@classDecoratorclass a { @readonly name() { return 1; } @log update() { console.log('update db'); }; @get get say() { return 1 } // @后面跟的值是一个函数,所以我们可以计算一个表达式,返回一个函数 @(false ? decoratorFactory(1) : decoratorFactory(2)) hello() { console.log('hello') } @decoratorFactory(2) world() { console.log('world') } @decoratorFactory(1) @decoratorFactory(2) double() { console.log('double') }}//a.prototype.name = 1 // throw errorconsole.log(new a().update())console.log(new a().hello())console.log(new a().world())console.log(new a().double())console.log(new a().say)
在当我文件夹下执行babel index.js -o index-babel.js得到
'use strict';var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();var _dec, _dec2, _dec3, _dec4, _class, _desc, _value, _class2;function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc;}/* target 类的prototype name 类prototype上的属性 descriptor 描述符*/function readonly(target, name, descriptor) { descriptor.writable = false; return descriptor;}// descriptor为数据描述符function log(target, name, descriptor) { // 保存原来的值 var value = descriptor.value; // 加钩子 descriptor.value = function () { console.log('log'); // 调用原来的值 value(); }; return descriptor;}// descriptor为存取描述符function get(target, name, descriptor) { var value = descriptor.get; descriptor.get = function () { console.log('log'); console.log(value()); }; return descriptor;}function decoratorFactory(type) { switch (type) { case 1: return function (target, name, descriptor) { var value = descriptor.value; descriptor.value = function () { console.log('you will say hello =>'); console.log(value()); }; return descriptor; }; case 2: return function (target, name, descriptor) { var value = descriptor.value; descriptor.value = function () { console.log('you will say world =>'); console.log(value()); }; return descriptor; }; }}function classDecorator(className) { className.flag = true; return className;}var a = (_dec = false ? decoratorFactory(1) : decoratorFactory(2), _dec2 = decoratorFactory(2), _dec3 = decoratorFactory(1), _dec4 = decoratorFactory(2), classDecorator(_class = (_class2 = function () { function a() { _classCallCheck(this, a); } _createClass(a, [{ key: 'name', value: function name() { return 1; } }, { key: 'update', value: function update() { console.log('update db'); } }, { key: 'hello', value: function hello() { console.log('hello'); } }, { key: 'world', value: function world() { console.log('world'); } }, { key: 'double', value: function double() { console.log('double'); } }, { key: 'say', get: function get() { return 1; } // @后面跟的值是一个函数,所以我们可以计算一个表达式,返回一个函数 }]); return a;}(), (_applyDecoratedDescriptor(_class2.prototype, 'name', [readonly], Object.getOwnPropertyDescriptor(_class2.prototype, 'name'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'update', [log], Object.getOwnPropertyDescriptor(_class2.prototype, 'update'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'say', [get], Object.getOwnPropertyDescriptor(_class2.prototype, 'say'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'hello', [_dec], Object.getOwnPropertyDescriptor(_class2.prototype, 'hello'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'world', [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, 'world'), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, 'double', [_dec3, _dec4], Object.getOwnPropertyDescriptor(_class2.prototype, 'double'), _class2.prototype)), _class2)) || _class);//a.prototype.name = 1 // throw errorconsole.log(new a().update());console.log(new a().hello());console.log(new a().world());console.log(new a().double());console.log(new a().say);
done。
2 在webpack中使用decorator
加配置
loaders: [ { test: /\.js|jsx$/, //是一个正则,代表js或者jsx后缀的文件要使用下面的loader loader: "babel-loader", query: { // 把es6转成es5 presets: ['es2015'], // 把decorator转成es5 plugins: ['transform-decorators-legacy'] } } ]
阅读全文
0 0
- 使用babel深入理解es7的decorator
- 深入理解ES7的async/await
- 深入理解ES7的async/await
- 深入理解ES7的async/await
- 使用Babel和ES7创建JavaScript模块
- ES7 decorator helloworld
- async的异步使用es7
- 快速理解和使用 ES7 await/async
- 快速理解和使用 ES7 await/async
- babel的使用
- babel的简单使用
- USING ES7 ASYNC/AWAIT TODAY WITH BABEL
- 关于decorator 的理解
- python decorator的理解
- 初学babel的简易使用
- 深入理解Python 装饰器(decorator)
- ES7 decorator 从入门到放弃
- Babel转码工具使es6\es7向es5转码
- 3401 数据结构实验之排序四:寻找大富翁
- 分类属性设置-可视化
- quartz之Hello
- redis设置密码和redis主从复制
- java中Volatile变量
- 使用babel深入理解es7的decorator
- 南邮CTF逆向题第二道ReadAsm2解题思路
- Spring事务传播机制-REQUIRES_NEW
- caffe中如何设置某层不参与反向传播
- Socket 长连接与短连接,心跳
- Spring框架 login.jsp跳转index.jsp
- 十三.ARM裸机学习之NandFlash详解
- 如何在linux中安装jdk
- 团队开发、代码维护利器——github