首页 web前端 前端问答 es6 装饰器怎么理解

es6 装饰器怎么理解

Jan 03, 2023 pm 04:14 PM
es6 装饰器

在es6中,装饰者模式是一种在不改变原类和使用继承的情况下,动态地扩展对象功能的设计理论;装饰者其本质就是一个普通的函数,用于扩展类属性和类方法。使用装饰器的优点:1、代码可读性变强了,装饰器命名相当于一个注释;2、在不改变原有代码情况下,对原来功能进行扩展。

es6 装饰器怎么理解

本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。

怎么理解ES6中 Decorator 的?

Decorator,即装饰器,从名字上很容易让我们联想到装饰者模式

简单来讲,装饰者模式就是一种在不改变原类和使用继承的情况下,动态地扩展对象功能的设计理论。

ES6中Decorator功能亦如此,其本质也不是什么高大上的结构,就是一个普通的函数,用于扩展类属性和类方法

这里定义一个士兵,这时候他什么装备都没有

class soldier{ 
}
登录后复制

定义一个得到 AK 装备的函数,即装饰器

function strong(target){
    target.AK = true
}
登录后复制

使用该装饰器对士兵进行增强

@strong
class soldier{
}
登录后复制

这时候士兵就有武器了

soldier.AK // true
登录后复制

上述代码虽然简单,但也能够清晰看到了使用Decorator(装饰器)两大优点:

  • 代码可读性变强了,装饰器命名相当于一个注释

  • 在不改变原有代码情况下,对原来功能进行扩展

装饰器的用法

Docorator修饰对象为下面两种:

  • 类的装饰

  • 类属性的装饰

类的装饰

当对类本身进行装饰的时候,能够接受一个参数,即类本身

将装饰器行为进行分解,大家能够有个更深入的了解

@decorator
class A {}

// 等同于

class A {}
A = decorator(A) || A;
登录后复制

下面@testable就是一个装饰器,target就是传入的类,即MyTestableClass,实现了为类添加静态属性

@testable
class MyTestableClass {
  // ...
}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true
登录后复制

如果想要传递参数,可以在装饰器外层再封装一层函数

function testable(isTestable) {
  return function(target) {
    target.isTestable = isTestable;
  }
}

@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true

@testable(false)
class MyClass {}
MyClass.isTestable // false
登录后复制

类属性的装饰

当对类属性进行装饰的时候,能够接受三个参数:

  • 类的原型对象

  • 需要装饰的属性名

  • 装饰属性名的描述对象

首先定义一个readonly装饰器

function readonly(target, name, descriptor){
  descriptor.writable = false; // 将可写属性设为false
  return descriptor;
}
登录后复制

使用readonly装饰类的name方法

class Person {
  @readonly
  name() { return `${this.first} ${this.last}` }
}
登录后复制

相当于以下调用

readonly(Person.prototype, 'name', descriptor);
登录后复制

如果一个方法有多个装饰器,就像洋葱一样,先从外到内进入,再由内到外执行

function dec(id){
    console.log('evaluated', id);
    return (target, property, descriptor) =>console.log('executed', id);
}

class Example {
    @dec(1)
    @dec(2)
    method(){}
}
// evaluated 1
// evaluated 2
// executed 2
// executed 1
登录后复制

外层装饰器@dec(1)先进入,但是内层装饰器@dec(2)先执行

注意

装饰器不能用于修饰函数,因为函数存在变量声明情况

var counter = 0;

var add = function () {
  counter++;
};

@add
function foo() {
}
登录后复制

编译阶段,变成下面

var counter;
var add;

@add
function foo() {
}

counter = 0;

add = function () {
  counter++;
};
登录后复制

意图是执行后counter等于 1,但是实际上结果是counter等于 0

装饰器的使用场景

基于Decorator强大的作用,我们能够完成各种场景的需求,下面简单列举几种:

使用react-redux的时候,如果写成下面这种形式,既不雅观也很麻烦

class MyReactComponent extends React.Component {}

export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
登录后复制

通过装饰器就变得简洁多了

@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}
登录后复制

将mixins,也可以写成装饰器,让使用更为简洁了

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

// 使用
const Foo = {
  foo() { console.log('foo') }
};

@mixins(Foo)
class MyClass {}

let obj = new MyClass();
obj.foo() // "foo"
登录后复制

下面再讲讲core-decorators.js几个常见的装饰器

@antobind

autobind装饰器使得方法中的this对象,绑定原始对象

import { autobind } from 'core-decorators';

class Person {
  @autobind
  getPerson() {
    return this;
  }
}

let person = new Person();
let getPerson = person.getPerson;

getPerson() === person;
// true
登录后复制

@readonly

readonly装饰器使得属性或方法不可写

import { readonly } from 'core-decorators';

class Meal {
  @readonly
  entree = 'steak';
}

var dinner = new Meal();
dinner.entree = 'salmon';
// Cannot assign to read only property 'entree' of [object Object]
登录后复制

@deprecate

deprecate或deprecated装饰器在控制台显示一条警告,表示该方法将废除

import { deprecate } from 'core-decorators';

class Person {
  @deprecate
  facepalm() {}

  @deprecate('功能废除了')
  facepalmHard() {}
}

let person = new Person();

person.facepalm();
// DEPRECATION Person#facepalm: This function will be removed in future versions.

person.facepalmHard();
// DEPRECATION Person#facepalmHard: 功能废除了
登录后复制

【相关推荐:javascript视频教程web前端

以上是es6 装饰器怎么理解的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

async是es6还是es7的 async是es6还是es7的 Jan 29, 2023 pm 05:36 PM

async是es7的。async和await是ES7中新增内容,是对于异步操作的解决方案;async/await可以说是co模块和生成器函数的语法糖,用更加清晰的语义解决js异步代码。async顾名思义是“异步”的意思,async用于声明一个函数是异步的;async和await有一个严格规定,两者都离不开对方,且await只能写在async函数中。

ES6怎么求数组反转 ES6怎么求数组反转 Oct 26, 2022 pm 06:19 PM

在ES6中,可以利用数组对象的reverse()方法来实现数组反转,该方法用于颠倒数组中元素的顺序,将最后一个元素放在第一位,而第一个元素放在最后,语法“array.reverse()”。reverse()方法会修改原始数组,如果不想修改需要配合扩展运算符“...”使用,语法“[...array].reverse()”。

小程序为什么要将es6转es5 小程序为什么要将es6转es5 Nov 21, 2022 pm 06:15 PM

为了浏览器兼容。ES6作为JS的新规范,加入了很多新的语法和API,但现代浏览器对ES6新特性支持度不高,所以需将ES6代码转为ES5代码。在微信web开发者工具中,会默认使用babel将开发者ES6语法代码转换为三端都能很好支持的ES5的代码,帮助开发者解决环境不同所带来的开发问题;只需要在项目中配置勾选好“ES6转ES5”选项即可。

es6怎么找出2个数组中不同项 es6怎么找出2个数组中不同项 Nov 01, 2022 pm 06:07 PM

步骤:1、将两个数组分别转为set类型,语法“newA=new Set(a);newB=new Set(b);”;2、利用has()和filter()求差集,语法“new Set([...newA].filter(x =>!newB.has(x)))”,差集元素会被包含在一个set集合中返回;3、利用Array.from将集合转为数组类型,语法“Array.from(集合)”。

es5和es6怎么实现数组去重 es5和es6怎么实现数组去重 Jan 16, 2023 pm 05:09 PM

es5中可以利用for语句和indexOf()函数来实现数组去重,语法“for(i=0;i

手把手教你用装饰器扩展 Python 计时器 手把手教你用装饰器扩展 Python 计时器 Apr 13, 2023 pm 08:46 PM

这是我们手把手教你实现 Python 定时器的第三篇文章。前两篇:分别是手把手教你实现一个 Python 计时器​,和用上下文管理器扩展 Python 计时器​,使得我们的 Timer 类方便用、美观实用。但我们并不满足于此,仍然有一个用例可以进一步简化它。假设我们需要跟踪代码库中一个给定函数所花费的时间。使用上下文管理器,基本上有两种不同的选择:1. 每次调用函数时使用 ​Timer:with Timer("some_name"): do_something()当我们在一

Python中的装饰器和上下文管理器是如何工作的? Python中的装饰器和上下文管理器是如何工作的? Oct 20, 2023 pm 07:04 PM

Python中的装饰器和上下文管理器是如何工作的?在Python中,装饰器和上下文管理器是两个非常有用的概念和功能。它们都是为了简化代码、增加代码可读性以及方便代码的重用。一、装饰器装饰器是Python中一种用于修改函数的行为的特殊函数。它允许我们在不修改原始函数的情况下对其进行包装或拓展。装饰器在许多Python的框架和库中被广泛使用,比如Flask、Dj

es6暂时性死区是什么意思 es6暂时性死区是什么意思 Jan 03, 2023 pm 03:56 PM

在es6中,暂时性死区是一个语法错误,是指let和const命令使区块形成封闭的作用域。在代码块内,使用let/const命令声明变量之前,该变量都是不可用的,在变量声明之前属于该变量的“死区”;这在语法上,称为“暂时性死区”。ES6规定暂时性死区和let、const语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。

See all articles