<commit_before># (@)computed

计算值(computed values)是可以根据现有的状态或其它计算值推导出的值。
概念上来说，它们与excel表格中的公式十分相似。
不要低估计算值，因为它们有助于使实际可修改的状态尽可能的小。
此外计算值还是高度优化过的，所以尽可能的多使用它们。

不要把 `computed` 和 `autorun` 搞混。它们都是响应式调用的表达式，但是，如果你想响应式的产生一个可以被其它 observer 使用的**值**，请使用 `@computed`，如果你不想产生一个新值，而想要达到一个**效果**，请使用 `autorun`。
举例来说，效果是像打印日志、发起网络请求等这样命令式的副作用。

如果任何影响计算值的值发生变化了，计算值将根据状态自动推导。
计算值在大多数情况下可以被 MobX 优化的，因为它们被认为是纯函数。
例如，如果前一个计算中使用的数据没有更改，计算属性将不会重新运行。
如果某个其它计算属性或 reaction 未使用该计算属性，也不会重新运行。
在这种情况下，它将被暂停。

这个自动地暂停是非常方便的。如果一个计算值不再被观察了，例如使用它的UI不复存在了，MobX 可以自动地将其垃圾回收。而 `autorun` 中的值必须要手动清理才行，这点和计算值是有所不同的。
如果你创建一个计算属性，但不在 reaction 中的任何地方使用它，它不会缓存值并且有些重新计算看起来似乎是没有必要的。这点有时候会让刚接触 MobX 的人们很困惑。
然而，在现实开发场景中，这是迄今为止最好的默认逻辑。如果你需要的话，可以使用 [`observe`](observe.md) 或 [`keepAlive`](https://github.com/mobxjs/mobx-utils#keepalive) 来强制保持计算值总是处于唤醒状态。

注意计算属性是不可枚举的，它们也不能在继承链中被覆盖。

## `@computed`

如果已经[启用 decorators](../best/decorators.md) 的话，可以在任意类属性的 getter 上使用 `@computed` 装饰器来声明式的创建计算属性。

```javascript
import {observable, computed} from "mobx";

class OrderLine {
    @observable price = 0;
    @observable amount = 1;

    constructor(price) {
        this.price = price;
    }

    @computed get total() {
        return this.price * this.amount;
    }
}
```

## `computed` 调节器

如果你的环境不支持装饰器，请使用 `computed(expression)` 调节器组合 `extendObservable` / `observable` 以引入新的计算属性。

从本质上来说，`@computed get propertyName() { }` 在构造函数中调用的 [`extendObservable(this, { propertyName: get func() { } })`](extend-observable.md) 的语法糖。

```javascript
import {extendObservable, computed} from "mobx";

class OrderLine {
    constructor(price) {
        extendObservable(this, {
            price: price,
            amount: 1,
            // valid:
            get total() {
                return this.price * this.amount
            },
            // also valid:
            total: computed(function() {
                return this.price * this.amount
            })
        })
    }
}
```

## Setters for computed values

It is possible to define a setter for computed values as well. Note that these setters cannot be used to alter the value of the computed property directly,
but they can be used as 'inverse' of the derivation. For example:

```javascript
const box = observable({
    length: 2,
    get squared() {
        return this.length * this.length;
    },
    set squared(value) {
        this.length = Math.sqrt(value);
    }
});
```

And similarly
<commit_msg>translate computed-decorator.md<40%><commit_after># (@)computed

计算值(computed values)是可以根据现有的状态或其它计算值推导出的值。
概念上来说，它们与excel表格中的公式十分相似。
不要低估计算值，因为它们有助于使实际可修改的状态尽可能的小。
此外计算值还是高度优化过的，所以尽可能的多使用它们。

不要把 `computed` 和 `autorun` 搞混。它们都是响应式调用的表达式，但是，如果你想响应式的产生一个可以被其它 observer 使用的**值**，请使用 `@computed`，如果你不想产生一个新值，而想要达到一个**效果**，请使用 `autorun`。
举例来说，效果是像打印日志、发起网络请求等这样命令式的副作用。

如果任何影响计算值的值发生变化了，计算值将根据状态自动推导。
计算值在大多数情况下可以被 MobX 优化的，因为它们被认为是纯函数。
例如，如果前一个计算中使用的数据没有更改，计算属性将不会重新运行。
如果某个其它计算属性或 reaction 未使用该计算属性，也不会重新运行。
在这种情况下，它将被暂停。

这个自动地暂停是非常方便的。如果一个计算值不再被观察了，例如使用它的UI不复存在了，MobX 可以自动地将其垃圾回收。而 `autorun` 中的值必须要手动清理才行，这点和计算值是有所不同的。
如果你创建一个计算属性，但不在 reaction 中的任何地方使用它，它不会缓存值并且有些重新计算看起来似乎是没有必要的。这点有时候会让刚接触 MobX 的人们很困惑。
然而，在现实开发场景中，这是迄今为止最好的默认逻辑。如果你需要的话，可以使用 [`observe`](observe.md) 或 [`keepAlive`](https://github.com/mobxjs/mobx-utils#keepalive) 来强制保持计算值总是处于唤醒状态。

注意计算属性是不可枚举的，它们也不能在继承链中被覆盖。

## `@computed`

如果已经[启用 decorators](../best/decorators.md) 的话，可以在任意类属性的 getter 上使用 `@computed` 装饰器来声明式的创建计算属性。

```javascript
import {observable, computed} from "mobx";

class OrderLine {
    @observable price = 0;
    @observable amount = 1;

    constructor(price) {
        this.price = price;
    }

    @computed get total() {
        return this.price * this.amount;
    }
}
```

## `computed` 调节器

如果你的环境不支持装饰器，请使用 `computed(expression)` 调节器组合 `extendObservable` / `observable` 以引入新的计算属性。

从本质上来说，`@computed get propertyName() { }` 在构造函数中调用的 [`extendObservable(this, { propertyName: get func() { } })`](extend-observable.md) 的语法糖。

```javascript
import {extendObservable, computed} from "mobx";

class OrderLine {
    constructor(price) {
        extendObservable(this, {
            price: price,
            amount: 1,
            // 有效:
            get total() {
                return this.price * this.amount
            },
            // 同样有效:
            total: computed(function() {
                return this.price * this.amount
            })
        })
    }
}
```

## 计算值的 setter

还可以为计算值定义 setter。注意这些 setters 不能用来直接改变计算属性的值，但是它们可以用来作为推导的“反转”。例如:

```javascript
const box = observable({
    length: 2,
    get squared() {
        return this.length * this.length;
    },
    set squared(value) {
        this.length = Math.sqrt(value);
    }
});
```

And similarly

{'fraction_non_alphanumeric': 0.12225304032430126, 'fraction_numerical': 0.002133560913164071, 'mean_word_length': 3.8479834539813855, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4022637', 'n_tokens_mistral': 2516, 'n_tokens_neox': 2708, 'n_words': 319}