美文网首页程序员
TypeScript:访问器装饰器

TypeScript:访问器装饰器

作者: Rollover | 来源:发表于2020-02-26 21:40 被阅读0次

回顾访问器

回顾学习编程的时候,碰到一些名词总是很困惑,毕竟我们自己想一个网名都要想很久,何况是一种代码规范名称,那么我们今天的主角就是 访问器

用语言去描绘一种事物,你得先知道它是干什么的,有什么用

在类里边,有属性,有方法,那我们在实例化对象后,调用对象的属性和方法就是在访问对象的属性和方法:

class Phone {
  public color: string = "green";
  public size: number = 15;

  call() {
    console.log("call");
  }
}

const p = new Phone();
console.log(p.color); // green
console.log(p.size); // 15
p.call(); // call

那我们在对象外部修改对象的属性,它也是一种访问:

class Phone {
  public color: string = "green";
  public size: number = 15;

  call() {
    console.log("call");
  }
}

const p = new Phone();
p.color = "yellow";
console.log(p.color); // yellow

这就是访问的两种形式,也就对应访问器的定义的 getter 和 setter。那么访问器也是一种函数,下面我们将代码改成访问器的形式:

class Phone {
  private _color: string = "green";

  get getColor(): string {
    return this._color;
  }

  set setColor(color: string) {
    this._color = color;
  }
}

const p = new Phone();
p.setColor = "yellow";
console.log(p.getColor);

可以看到访问器的定义方式是在函数前面加 get 或 set,调用方式和调用属性一样,不需要加括号。那么访问器看似和普通的属性调用一样,结果也一样,到底有什么用呢!我们看,在没有使用访问器的时候,如果属性是 public 的时候,外部可以随意访问,随意修改,而且是一步就能修改了,中间没有任何可处理的空间

class Phone {
  public color: string = "green";
}

const p = new Phone();
p.color = "yellow";
console.log(p.getColor); // yellow

有了访问器,我们可以对类的属性进行一些预处理,这里,访问器相当于对属性进行一层包装,使得属性的使用性变强,如下代码,我们对对象外部修改 _color 做了长度的限制,长度没超过 10 将不会改变 _color 属性

class Phone {
  private _color: string = "green";

  get getColor(): string {
    return this._color;
  }

  set setColor(color: string) {
    if (color.length < 10) {
      return;
    }
    this._color = color;
  }
}

const p = new Phone();
p.setColor = "yellow";
console.log(p.getColor); // green

访问器装饰器 VS 方法装饰器

在了解了访问器的后,我们来看访问器装饰器,那么既然访问器也是一个函数,那么它的用法和方法装饰器是一样的(参考上文 TypeScript:方法装饰器
),但其中又有点区别,我们看下面代码:

function addDecorator(
  target: any,
  key: string,
  descriptor: PropertyDescriptor
) {
  console.log("target   ->", target);
  console.log("key      ->", key);
  console.log("descript ->", descriptor);
}

class Phone {
  private _color: string = "green";

  get getColor() {
    return this._color;
  }

  @addDecorator
  set setColor(color: string) {
    this._color = color;
  }
}

运行代码,结果如下:


这里我们没有对 get 做装饰器,所以 get 是undefined

注意 TypeScript 不允许同时装饰一个成员的 get 和 set 访问器。取而代之的是,一个成员的所有装饰的必须应用在文档顺序的第一个访问器上。这是因为,在装饰器应用于一个属性描述符时,它联合了 get 和 set 访问器,而不是分开声明的。

看访问器的装饰器属性,我们来对比下方法装饰器的属性:

function addDecorator(
  target: any,
  key: string,
  descriptor: PropertyDescriptor
) {
  console.log("target   ->", target);
  console.log("key      ->", key);
  console.log("descript ->", descriptor);
}

class Phone {
  private _color: string = "green";

  get getColor() {
    return this._color;
  }

  set setColor(color: string) {
    this._color = color;
  }

  @addDecorator
  call() {}
}

那么运行的结果如下:


对比结果:方法装饰器的 descriptor 有 value 和 witable 属性,但没有 get 和 set 属性;访问器装饰器有 get 和 set 属性,但没有 value 和 witable 属性。
原文链接

相关文章

网友评论

    本文标题:TypeScript:访问器装饰器

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