You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Signals优势解析:对比普通变量实现方式

Angular Signals 对比普通变量的核心优势

结合你给出的代码,我们可以清晰看到Signals相比普通变量的几个关键优势:

1. 自动维护关联状态,减少重复劳动

看你的inc()方法:

  • 用普通变量时,每次计数增加,你需要手动更新myCount、myCountDouble、myCountType三个变量,每一个关联值的计算逻辑都要重复写在更新操作里
  • 用Signals时,只需要调用this.count.update((c) => c + 1)更新核心计数,double和countType作为computed信号会自动根据依赖的count重新计算,不用再手动维护关联值的更新逻辑,彻底避免漏更、错更的风险

2. 自动追踪变更,副作用精准执行

Signals的effect会自动追踪它依赖的信号,只有当依赖信号(比如count)发生变化时,effect才会触发。

  • 你代码里的构造函数中,effect会在count变化时自动打印日志,不用在inc()和reset()里重复编写打印逻辑
  • 而普通变量要实现类似的监听,必须在每一处更新变量的地方手动调用副作用代码(比如你在inc()里写的console.log('Old Way', ...)),如果后续新增了更新myCount的地方,很容易忘记加这段逻辑

3. 依赖关系一目了然

用computed定义的信号,直接就能看出它的依赖来源:比如double明确依赖count(),countType也明确依赖count(),状态之间的关系清晰可见。
而普通变量的依赖关系完全隐藏在更新代码里,别人要理解myCountDouble和myCount的关系,必须去读inc()和reset()的实现,维护成本更高。

4. 跨场景的灵活复用

信号可以脱离组件类存在,比如你代码里在组件外定义的const myValue = signal(10000),可以在任何地方读取、更新它,还能通过effect监听它的变化。
如果是普通变量,要在组件外共享并监听变化,得额外借助服务、RxJS等工具,复杂度高很多。

5. 适配未来的性能优化

目前你的示例还依赖Zone.js,但Angular官方正式推出Signals后,会配合基于信号的变更检测策略——只有依赖信号发生变化的组件和模板部分才会更新,相比Zone.js的全量检测,性能提升明显。普通变量无法适配这种高效的变更检测机制。


你的代码示例

import 'zone.js/dist/zone';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { signal } from './signals/signal';
import { computed } from './signals/computed';
import { effect } from './signals/effect';
import { TestArraysCmp } from './testing-arrays.component';
import { TestObjectsCmp } from './testing-objects.component';

/*
  ⚠️ Please keep in mind that this is only the signals implementation. We still depend on zone and current CD strategy to propagate change in the template which might not be the case when Angular releases signals officially!
*/

// Signals are primitives, so we can use them outside the component class
const myValue = signal(10000);

effect(() => {
  console.log('MyValue changed', myValue());
});

// Uncomment this
// setInterval(() => {
//   myValue.update((s) => s - 1);
// }, 1000);

@Component({
  selector: 'my-app',
  standalone: true,
  template: `
    <div>Count: {{ count() }}</div>
    <div>Double: {{ double() }}</div>
    <div>MyCount: {{myCount}}</div>
    <div>MyDoubleCount: {{myCountDouble}}</div>
    <button (click)="inc()">Increase</button>
    <button (click)="reset()">Reset</button>

    <br>
    <!-- <test-arrays /> -->
    <!-- <test-objects /> -->

  `,
  imports: [TestArraysCmp, TestObjectsCmp],
})
export class App {
  myCount: number = 0;
  myCountDouble: number = 0;
  myCountType: string;

  count = signal(0);

  double = computed(() => this.count() * 2);

  countType = computed(() => (this.count() % 2 === 0 ? 'even' : 'odd'));

  constructor() {
    effect(() => {
      console.log('Count changed', this.count());
      console.log(this.count(), 'is', this.countType());
    });
  }

  inc() {
    this.count.update((c) => c + 1);
    this.myCount = this.myCount + 1;
    this.myCountDouble = this.myCount * 2;
    this.myCountType = this.myCount % 2 === 0 ? 'even' : 'odd';
    console.log('Old Way', this.myCount, 'is', this.myCountType);
  }
  reset() {
    this.count.set(0);
    this.myCount = 0;
    this.myCountDouble = 0;
    this.myCountType = '';
  }
}

bootstrapApplication(App);

内容的提问来源于stack exchange,提问作者Ka Tech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:37:05