乐趣区

关于javascript:一个-JSer-的-Dart-学习日志二变量常量

本文是“一个 JSer 的 Dart 学习日志”系列的第二篇,本系列文章次要以开掘 JS 与 Dart 异同点的形式,在温习和坚固 JS 的同时安稳地过渡到 Dart 语言。
鉴于作者尚属 Dart 初学者,所以意识可能会比拟浮浅和全面,如您慧眼识虫,心愿不吝指正。
如无非凡阐明,本文中 JS 蕴含了自 ES5 至 ES2021 的全副个性,Dart 版本则为 2.0 以上版本。

1. 关键字

(外表上的)共同点

  • 变量关键字 var
  • 常量关键字 const

不同点

1.1 var 变量的作用域

  • JS 中 var 关键字申明的变量作用域是所在函数作用域,与此关联的还有一个很经典的例子(就是 for循环里 setTimeout 那个,不赘述);
  • Dart 中 var 关键字申明的变量作用域是块级作用域。
> /* JS */                          | // Dart
> function foo(){                   | foo(){>     if(true){|     if(true){
>         var a = 321;              |         var a = 321;
>     }                             |     }
>     console.log(`a = ${a}`);      |     print('a = $a');
>   /* a = 321; */                  | // Getter not found: 'a'.
> }                                 | }

1.2 const 的语义不同

  • JS 中,const 申明的常量能够是运行过程中长期计算得来的;
  • Dart 里,const 申明的常量必须是编译时常量,即在运行前就必须确定它的值。
> /* JS */                          | // Dart
> var a = Date.now();    /* OK */   | var a = new DateTime.now();   // OK
> const b = Date.now();  /* OK */   | const b = new DateTime.now(); // NOT OK

2. 各自的特色

这里算是两种语言的特色语法大赏,因而不再列举它们的共同点。

2.1 letfinal,各自的特色关键字

  • JS 中引入了 let 关键字来补救 var 的设计缺点,然而 Dart 中的 var 自身没有这些缺点,大略是因而,Dart 没有 let 关键字,舍不得 let 的话,能够去隔壁学习 Rust;
  • Dart 中的 const 关键字申明的常量须要在编译时确定值,然而在日常编程的时候,咱们有需要固定一些在运行中能力确定其值的变量,避免意外被批改,也能够给编译器提供肯定的优化参考,这时候咱们能够用 final,其个性能够参考 JS 中的 const

2.2 Dart 反对申明变量类型

  • Dart 是一门强类型的语言,申明变量 / 常量的同时也能够显式地申明其类型,但变量类型与 var 关键字不能并列应用。

    > var int a = 0; // 谬误,`var` 与变量名不得并列应用
    > var     a = 0; // 正确,Dart 会推断类型
    >     int a = 0; // 正确,失去一个类型为 int 的变量
    >
    > const int a = 0; // 正确,失去一个类型为 int 的编译时常量
    > final int a = 0; // 正确,失去一个类型为 int 的常量
    >
    > Set<num> a = {0}; // 正确,所得 Set 可蕴含 int 和 double 子项

事实上,如果不显式申明变量类型,Dart 会依据所赋的值来推断变量的类型。var a = 0中,a的类型将被推断为 intvar a = 0.1中,a 的类型则为 double

2.3 Dart 用 const 确定编译时常量

Dart 中的 const 申明的变量值在编译时就曾经确定了,这应该是出于性能优化思考,将一些运行时的计算量转移到编译过程,或防止在同一程序中反复执行的额定开销。

  • 编译时就能确定变量值这么好的性能,如果只有 const 能享受的话,就太节约了,所以申明变量的值为简单数据类型的时候,能够用 const 关键字标名这个值是一个编译时常量:

    var a = const {123456};
    Set<num> a = const {123456};

    ,但这个语法不适用于简略类型:

    var a = const 123456; // 这将无奈通过编译

2.4 JS 省略关键字 var

  • 在 JS 中,能够省略 var,间接命名一个变量并赋值,这个变量会主动成为一个全局变量,此即 JS 的“隐式全局变量”,这是一个名声不佳的 JS 个性,开发中应防止应用;

本文 2.2 曾经提到:Dart 的 var 关键字与类型申明不能并列应用,从某种意义上来讲,也算是省略了关键字 var

2.5 Dart 不存在变量晋升

  • 变量晋升也是 JS 中的一个槽点,所幸 ES6+ 的 letconst 以“死区”的形式防止了这个槽点,证实 TC39 也不喜爱这个个性;
  • Dart 是一门“失常”的语言,遵循变量先申明后应用的准则,不存在变量晋升。
> /* JS */                         | // Dart
> var b = a + 1;                   | var b = a + 1;
> var a = 100;                     | var a = 100;
> console.log(`b = ${b}`);         | print('b = $b');
> // b = NaN                       | // 无奈通过编译

3. 总结 & 比照

参见下表:

个性 JS Dart
var 函数级 变量关键字 块级变量关键字
const 常量关键字 编译时常量 关键字
let 块级 变量关键字 没有此关键字
final 没有此关键字 运行时常量 关键字
类型申明 不反对类型申明 反对类型申明,也可交由 Dart 主动推断类型
退出移动版