当前位置: 首页 > Web前端 > JavaScript

一个JSer的Dart学习日志(二):变量、常量

时间:2023-03-26 20:33:12 JavaScript

本文是“一个JSer的Dart学习日志”系列文章的第二篇。本系列文章主要是回顾和巩固JS,同时顺利过渡到Dart语言。由于笔者还是Dart的初学者,所以理解可能是肤浅的、片面的。如果你有慧眼,还望指正。如无特殊说明,本文JS包含ES5到ES2021的所有特性,Dart版本为2.0及以上版本。1.关键字(表观)共同点变量keywordvar;常量关键字const。区别1.1var变量的作用域JS中var关键字声明的变量作用域就是函数的作用域。还有一个很经典的例子与之相关(就是for循环中的setTimeout,就不赘述了);Dart中的var关键字声明的变量作用域是块级作用域。>/*JS*/|//Dart>函数foo(){|foo(){>如果(真){|如果(真){>变量a=321;|vara=321;>}|}>console.log(`a=${a}`);|print('a=$a');>/*a=321;*/|//未找到Getter:'a'。>}|}1.2const的语义不同。在JS中,可以在运行过程中临时计算const声明的常量;在Dart中,const声明的常量必须是编译时常量,即它的值必须在运行前确定。>/*JS*/|//Dart>vara=Date.now();/*好的*/|vara=newDateTime.now();//OK>constb=Date.now();/*好*/|constb=newDateTime.now();//不行2。它们各自的特点这是两种语言的特殊语法奖,所以这里不再列出它们的共同点。2.1final、late和let,它们各自的特色关键字JS中引入let关键字是为了弥补var的设计缺陷,但是Dart中的var本身不存在这些缺陷,可能也是因为如此,Dart没有let关键字,如果你舍不得用let,可以去隔壁学Rust;Dart中const关键字声明的常量需要在编译时确定值,但是在日常编程中,我们需要固定一些只能在运??行时确定值的变量,以防止误修改。它可以为编译器提供一定的优化参考。这时候我们可以使用final,它的特性可以参考JS中的const;JS中没有指定初始值的变量默认值为undefined,而在Dart中,虽然也有“nullsafety”默认值为null,但是为了写出更健壮的代码,可以使用late来声明变量,表示该变量没有初值,时机成熟时会被赋值。/*仅限JS*/|/*仅限Dart*/>letx=0;|>|finalx=newDateTime.now();>letmsg;|lateStringmsg;2.2Dart支持声明变量类型Dart是一门强类型语言,在声明变量/常量时,也可以显式声明其类型,但变量类型和var关键字不能同时使用。>变量inta=0;//错误,`var`不能与变量名一起使用>vara=0;//对,Dart会推断类型>inta=0;//对,得到一个int变量>>constinta=0;//正确,得到一个int类型的编译时常量>finalinta=0;//正确,得到一个int类型的常量>>Seta={0};//正确,生成的Set可以包含int和double子项实际上,如果不显式声明变量类型,Dart会根据赋值推断变量类型。在vara=0中,a的类型将被推断为int;在vara=0.1中,a的类型将为double。2.3Dart使用const来确定编译时常量。Dart中const声明的变量值在编译时就已经确定了。这应该是出于性能优化的考虑,将一些运行时的计算转移到编译过程中,或者避免同一个程序中重复执行的额外开销。这么好的编译期确定变量值的功能,如果只有const才能享受,那就太浪费了,所以在声明变量值为复杂数据类型时,可以使用const关键字来标记作为编译时常量的值:vara=const{123456};Seta=const{123456};,但这种语法不适用于简单类型:vara=const123456;//这不会编译。2.4JS省略关键字var在JS中可以省略var,直接命名一个变量并赋值,这个变量会自动成为全局变量,也就是JS的“隐式全局变量”,这是JS臭名昭著的特性,开发中应避免;如本文2.2所述:Dart的var关键字和类型声明不能并排使用。从某种意义上说,关键字var也被省略了。2.5Dart没有变量提升。变量提升也是JS中的槽点。幸运的是,ES6+的let和const在一个“死区”中避开了这个插槽,这证明TC39不喜欢这个特性;Dart是一门“普通”语言,遵循变量先声明后使用的原则,没有变量提升。>/*JS*/|//飞镖>varb=a+1;|变量b=a+1;>变量a=100;|vara=100;>console.log(`b=${b}`);|print('b=$b');>//b=NaN|//不能通过编译字编译时常量关键字let块级变量关键字没有this关键字final没有this关键字运行时常量关键字late没有this关键字没有指定初始值类型声明的变量关键字不支持类型声明支持类型声明类型可以被Dart自动推断