zoukankan      html  css  js  c++  java
  • js基石之---es7的decorator修饰器

    es7的decorator修饰器

    装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法。

    decorator就是给类添加或修改类的变量与方法的。

    装饰器是一种函数,写成@ + 函数名。它可以放在类和类方法的定义前面。

    @frozen class Foo {
      @configurable(false)
      @enumerable(true)
      method() {}
    
      @throttle(500)
      expensiveMethod() {}
    }

    上面代码一共使用了四个装饰器,一个用在类本身,另外三个用在类方法。它们不仅增加了代码的可读性,清晰地表达了意图,而且提供一种方便的手段,增加或修改类的功能。

    1.修改类

    @addType
    class human{}
    function addType(target){
      target.age=27;
      target.name=hyh;
      target.sex=male;
      target.hight=178;
      console.log('此对象被修改了')
    }
    console.log(new human())

    上面代码中,@addType就是一个装饰器。它修改了human这个类的行为,为它加上了静态属性age name sex hight等等。addType函数的参数target是human类本身。

    2.修改类的方法

    class Dabao {
        @setAttr
        cxh(){
            return true
        } 
    }
    function setAttr(targt, name, decorator) {
        decorator.writable = false
        return 
    }
    
    var dabao = new Dabao;
    console.log(dabao.cxh)
    dabao.cxh = () => {
        return false
    }
    console.log(dabao.cxh)

    3. 装饰器可接受多个传参,第一个参数为修饰target  ,如果觉得一个参数不够用,可以在装饰器外面再封装一层函数。

    装饰器testable可以接受参数,这就等于可以修改装饰器的行为。

    function testable(isTestable) {
      return function(target) {
        target.isTestable = isTestable;
      }
    }
    
    @testable(true)
    class MyTestableClass {}
    MyTestableClass.isTestable // true
    
    @testable(false)
    class MyClass {}
    MyClass.isTestable // false

    上面代码中,装饰器函数testable是在目标类的prototype对象上添加属性,因此就可以在实例上调用。

    下面是另外一个例子。

    // mixins.js
    export function mixins(...list) {
      return function (target) {
        Object.assign(target.prototype, ...list)
      }
    }
    
    // main.js
    import { mixins } from './mixins'
    
    const Foo = {
      foo() { console.log('foo') }
    };
    
    @mixins(Foo)
    class MyClass {}
    
    let obj = new MyClass();
    obj.foo() // 'foo'

    实际开发中,React 与 Redux 库结合使用时,常常需要写成下面这样。

    class MyReactComponent extends React.Component {}
    
    export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);

    有了装饰器,就可以改写上面的代码。

    @connect(mapStateToProps, mapDispatchToProps)
    export default class MyReactComponent extends React.Component {}

    相对来说,后一种写法看上去更容易理解。

    4.装饰器不能用于装饰函数

    5.Mixin

    在装饰器的基础上,可以实现Mixin模式。所谓Mixin模式,就是对象继承的一种替代方案,中文译为“混入”(mix in),意为在一个对象之中混入另外一个对象的方法。

    请看下面的例子。

    const Foo = {
      foo() { console.log('foo') }
    };
    
    class MyClass {}
    
    Object.assign(MyClass.prototype, Foo);
    
    let obj = new MyClass();
    obj.foo() // 'foo'

    上面代码之中,对象Foo有一个foo方法,通过Object.assign方法,可以将foo方法“混入”MyClass类,导致MyClass的实例obj对象都具有foo方法。这就是“混入”模式的一个简单实现。

    下面,我们部署一个通用脚本mixins.js,将 Mixin 写成一个装饰器。

    export function mixins(...list) {
      return function (target) {
        Object.assign(target.prototype, ...list);
      };
    }

    然后,就可以使用上面这个装饰器,为类“混入”各种方法。

    import { mixins } from './mixins';
    
    const Foo = {
      foo() { console.log('foo') }
    };
    
    @mixins(Foo)
    class MyClass {}
    
    let obj = new MyClass();
    obj.foo() // "foo"
  • 相关阅读:
    MyEclipse连接Oracle,出现ORA00604和ORA12705异常
    MyEclipse连接Oracle,出现ORA00604和ORA12705异常
    SSH Secure Shell Client 乱码问题
    android开发(20) 使用adb建立pc和android设备之间的连接。usb连接方式。
    android开发(22)使用正则表达式 。从一个字符串中找出数字,多次匹配。
    .net 中,使用c# 语言 ,执行exe程序。
    [转载]大数据存取的选择:行存储还是列存储?
    android开发(21)蜂鸣提示音和震动提示的实现。
    arcgis for android 学习 (8) 空间查询 点击某点,选中该点所在单位区域。
    android开发(24)使用SQLiteOpenHelper的onUpgrade实现数据库版本升级
  • 原文地址:https://www.cnblogs.com/style-hyh/p/12862853.html
Copyright © 2011-2022 走看看