[ECMAScript] 配置和使用Decorator

1. 目录结构

- dist
    example.js
- example
    index.html
    index.js
+ node_modules

.babelrc
package.son
webpack.config.js

2. 环境配置

(1)配置工程依赖:./package.json

{
  "name": "test-decorator",
  "version": "1.0.0",
  "dependencies": {},
  "devDependencies": {
    "babel-loader": "^6.2.10",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-preset-stage-0": "^6.24.1",
    "webpack": "^1.13.1"
  }
}

(2)配置Babel:./babelrc

{
    "presets": [
        "es2015",
        "stage-0"
    ],
    "plugins": [
        "transform-decorators-legacy"
    ]
}

(3)配置Webpack:./webpack.config.js

module.exports = {
    entry: {
        example: './example/index.js'
    },
    output: {
        path: './dist/',
        filename: '[name].js',
        libraryTarget: 'umd'
    },
    module: {
        loaders: [{
            test: /.js$/,
            loader: 'babel-loader'
        }]
    }
};

3. 用例

const D1 = Class => {

    //Class没有v0这个属性
    console.log(Class.v0);    //undefined
    Class.v0 = 1;
    return Class;
};

const D2 = Class => {

    //可以获取静态属性
    console.log(Class.v1);    //0
    Class.v1 = 2;
    return Class;
}

const D3 = Class => {
    const f1 = Class.f1;

    //可以获取静态属性,属性为箭头函数
    console.log(f1);    //x => x+1

    Class.f1 = z => f1(z) + 1;
    return Class;
}

const D4 = instance => {

    //当实例为public class field时,无法获取实例属性
    console.log(instance.v2);    //undefined
    instance.v2 = 4;
    return instance;
}

const D5 = instance => {

    //当实例为public class field时,无法获取实例属性
    console.log(instance.f2);    //undefined
    instance.f2 = z => z + 4;
    return instance;
};

const D6 = instance => {
    const f3 = instance.f3;

    //实例方法,可以获取
    console.log(f3);    //x => x+1

    instance.f3 = z => f3(z) + 4;
    return instance;
};

@D1
class A {

    @D2
    static v1 = 0;    //static public class field

    @D3
    static f1 = x => x + 1;    //static public class field

    @D4
    v2 = 0;    //public class field

    @D5
    f2 = x => x + 1;    //public class field

    //You can't attach decorators to a class constructor
    constructor() { }

    @D6
    f3(x) {    //mothod
        return x + 1;
    }
};

console.warn(A.v0);    //1
console.warn(A.v1);    //2
console.warn(A.f1(1));    //3

const a = new A;
console.warn(a.v2);    //4
console.warn(a.f2(1));    //5
console.warn(a.f3(1));    //6

注意事项:
(1)constructor不能添加decorator
(2)decorator是一个函数。
如果添加在类上或者类的静态字段上,参数为这个类,返回值将替换原来的类。

const f = Class => class B { };

@f
class A{

}

console.log(A);    //B

如果添加在实例字段或者方法上,参数为实例,返回值必须是一个对象,且该对象将被丢弃。

const f = x => {
    const fn = x.fn;
    x.fn = () => fn() + 1;

    return {
        v: 2
    };
};

class A {

    @f
    fn() {
        return 1;
    }

    gn() {
        console.log(this.fn());    //2

        //this还是原来的实例,而不是{v:2}
        console.log(this.v);    //undefined
    }
}

const a = new A;
a.gn();

(3)decorator修饰public class field时,如果该field是一个实例字段,则通过decorator的参数(参数是当前类的实例)无法获取该字段。
(可能是Babel的问题

(4)不在类中的普通函数,不支持decorator。

const f = x => x;

// Leading decorators must be attached to a class declaration
@f
function g() {

}

console.log(g);

参考

Class and Property Decorators
babel-plugin-transform-decorators-legacy

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,555评论 19 139
  • 前言 webpack2和vue2已经不是新鲜东西了,满大街的文章在讲解webpack和vue,但是很多内容写的不是...
    技术宅小青年阅读 6,681评论 4 43
  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,368评论 7 35
  • 组合的意思就是,一个对象是另一个对象的数据成员,比如手电筒和电池。 一个充电电筒中的电池、LED灯、按钮…… 都可...
    望月成三人阅读 288评论 0 0
  • 从日本回来已经好些天了,回顾整个这次日本之行,整个就是暴走之旅: 2月25日15002步 踏上旅途:成都-上海-大...
    soluna阅读 959评论 0 3

友情链接更多精彩内容