javascript之变量声明
JavaScript是一门弱类型语言,它并不像其他强类型语言那样有多种变量类型的声明形式,如:int, double, string… 等,在JavaScript中声明变量统一使用 var 关键字。
例如想要声明一个整数来使用,可以使用 var num = 1;
这样的语句,声明一串字符串也一样 var str = 'string';
,声明一个布尔值、数组、对象都是使用 var
这个关键字: var boo = true; var arr = [1,2,3]; var obj = { x: 1, y: 2};
1 | var num = 1; // 声明一个整数 |
在ES5标准之前,只有 var
这一个关键字用来声明一个可以使用的变量(函数暂不讨论)。而在ES6标准中,在此之上添加了两个新的声明变量的关键字,let
和 const
。严格说起来应该是一个声明变量,一个声明常量, const
就是用来声明常量的关键字。
let与var有什么不同?
这需要从变量的作用域说起。在ES5标准之前,JavaScript中只有两种作用域:全局作用域与函数作用域。全局作用域的变量可以在代码运行中的任何位置访问到,而函数作用域的变量只有在该函数内部能够访问到。而在ES6标准中新增了一个块级作用域的概念,let关键字就是对应块级作用域的概念的变量声明。通过let声明的变量只有在声明时所在的块级作用域的范围内能访问,所谓块级作用域指的是代码中被{}
包裹起来的代码(对象除外),函数体也属于代码块。
let
与 var
另一个不同的地方在于:
var
声明的变量可以重复声明,但只有第一次声明有效,且有声明提升;let
声明的变量不能再次声明,否则会报错,且let声明的变量并没有声明提升。
1 | { |
const常量
所谓常量,与变量相反。变量就是可以改变的量,而常量则是一旦声明,就无法改变的量。有些数据在使用过程中是不会改变的,甚至有些就是固定不变的值,如圆周率PI,像这样的数据,使用 var
声明,之后一直不做改动自然也是不算错的,但是使用 const
声明的话,更能够表达出符合的语义,用 const PI = 3.14;
代替 var PI = 3.14;
更能让人清楚地知道这是一个常量。
const声明的变量的作用域范围同let关键字,也是声明变量所在的块级作用域,用const声明的变量也不能重复声明,且没有变量声明提升,另外不能通过赋值来改变常量的值。
基于这几点,在声明一个常量的时候就要将这个常量的值赋给它,而不能先声明一个没有值的常量,再在之后赋值。
1 | const PI = 3.14; |
关于变量声明提升
JavaScript是解释型语言,解析一句执行一句,为了提高效率,在代码解析执行之前,有一个预解析的过程。在预解析时,代码并不会执行,系统只会检查当前作用域(函数内部的代码不会检查,只有在调用函数时,才会重复 “预解析->执行”
这样的步骤)的代码有没有语法上的错误和代码中的变量声明关键字 var
和函数声明的关键字 function
。
在遇到这两种声明时,系统会在内存中预先记录下声明的变量名和函数名,也就是标识符。在预解析结束后,运行代码之前,系统就得到了有哪些标识符是可以作为变量来使用的,如果使用了系统未记录的标识符,也就是没有声明的变量,这时系统就会抛出一个引用错误 ReferenceError: xxx is not defined
。
在预解析过程中,如果遇到了同一个标识符多次声明,是不会多次记录的,只会记录第一次。如果同一个标识符既有变量声明var,又有函数声明function,最终记录下来的标识符是一个函数,遵循的原则是先有什么就记录什么,函数声明会记录两件事,一个同变量声明,记录该标识符可以使用,第二个记录该标识符指向一个函数。
所以有说法 函数是JavaScript中的一等公民。
但要知道该记录只保持在预解析结束,运行代码之前。
在运行代码过程中,需要根据实际情况判断标识符到底是一个变量还是一个函数。