[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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容

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