美文网首页JavaScript
[ECMAScript] 配置和使用Decorator

[ECMAScript] 配置和使用Decorator

作者: 何幻 | 来源:发表于2017-04-10 19:36 被阅读836次

    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

    相关文章

      网友评论

        本文标题:[ECMAScript] 配置和使用Decorator

        本文链接:https://www.haomeiwen.com/subject/yzkeattx.html