71

我正在查看一些 ES6 代码,但我不明白将 @ 符号放在变量前面时的作用。我能找到的最接近的东西与私有领域有关?

我从redux 库中查看的代码:

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'redux/react';
import Counter from '../components/Counter';
import * as CounterActions from '../actions/CounterActions';

@connect(state => ({
  counter: state.counter
}))
export default class CounterApp extends Component {
  render() {
    const { counter, dispatch } = this.props;
    return (
      <Counter counter={counter}
               {...bindActionCreators(CounterActions, dispatch)} />
    );
  }
}

这是我在该主题上找到的一篇博文:https ://github.com/zenparsing/es-private-fields

在这篇博文中,所有示例都在类的上下文中 - 在模块中使用符号时意味着什么?

4

3 回答 3

87

我发现接受的答案不足以帮助我解决这个问题,所以我添加了更多细节来帮助其他找到这个的人。

问题是不清楚究竟什么是装饰器。给出的示例中的装饰器不仅是@符号,还是@connect函数。简单来说,@connect函数就是装饰CounterApp

在这种情况下它在做什么?它将值与类的道具联系起来。state.counter请记住,在 redux 中,该connect函数有两个参数:mapStateToPropsmapDispatchToProps. 在这个例子中,它只接受一个参数 - mapStateToProps

我没有对此进行过多调查,但这似乎是一种封装你的 state-to-props 和 dispatch-to-props 映射的方法,以便它们伴随你的组件而不是位于不同的文件中。

于 2016-05-24T14:49:27.977 回答
39

这是一个装饰器。这是一个要添加到 ECMAScript 中的提案。有多个 ES6 和 ES5 等效示例:javascript-decorators

装饰器动态地改变函数、方法或类的功能,而无需直接使用子类或更改被装饰函数的源代码。

它们通常用于控制访问、注册、注释。

于 2015-08-04T23:52:25.903 回答
18

是什么@myDecorator()

javascript 中的@符号代表装饰器。装饰器不存在,ES6因此您使用装饰器的 in 代码可能被转换为可以在任何浏览器中运行的 javascript 版本。

什么是装饰器?

装饰器动态扩展(即装饰)对象的行为。在运行时添加新行为的能力是由一个装饰器对象完成的,该对象将自己“包裹”在原始对象周围。装饰器不仅仅是 javascript 中的一个概念。它是所有面向对象编程语言中使用的设计模式。这是来自维基百科的定义:

在面向对象编程中,装饰器模式是一种设计模式,它允许将行为动态添加到单个对象,而不会影响同一类中其他对象的行为。装饰器模式通常有助于遵守单一职责原则,因为它允许在具有独特关注领域的类之间划分功能

为什么要使用装饰器?

使用装饰器时,可以在运行时修改对象的功能。例如,在您的代码中,您只需导入装饰器并将其添加到您的CounterApp类中。现在您 CounterApp已经动态添加了功能,而您不知道实现细节。

例子:

// decorator lights is a function which receives the class as an argument
let lights = function(tree) {
  // The behaviour of the class is modified here
  tree.treeLights = 'Christmas lights'
}

@lights  // the decorator is applied here
class ChristmasTree {}

console.log(ChristmasTree.treeLights);  // logs Christmas lights
于 2018-10-16T19:01:52.373 回答