JavaScript是一门弱类型语言,可以不用事先声明而直接使用,虽然这种方式方便简洁,但是很容易引起变量命名方面的错误,容易造成全局变量污染,因此不建议这样做。在JavaScript中,变量的声明有三种方式,分别是
var、let、const,其中,var在 ECMAScript 的所有版本中都可以使用,let和const是ES6新增的语法,只能在 ECMAScript 6 及更晚的版本中使用,下面笔者就来简单的介绍下这三种变量声明的方式。
变量
在此之前,我们需要了解变量是什么,从字面意思来说,变量就是数值可以发生变化的量;从编程角度来讲,变量就是计算机中用来存储数据的容器,其本质就是程序在内存中申请的一块用来存放数据的小空间。
在JavaScript 中的变量是松散类型(弱类型)的,所谓松散类型就是用来保存任何类型的数据,在定义变量的时候不需要指定变量的数据类型。
变量的命名规范
- 首字母必须是字母、下划线(-)或者美元符号($)。
- 其他字母可以是下划线(_)、美元符号($)、字母或者数字。
- 一般采用驼峰法:第一个字母小写,其余有意义的单词首字母大写。
- 变量名是区分大小写的,不能是关键字或保留字。
JavaScript的关键字(保留字)
ECMA-262 第 6 版规定的所 有关键字如下:
var 声明
局部作用域
作用域概述:变量起作用(可被访问)的范围。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了变量名冲突。
全局作用域:作用于所有代码执行的环境;局部作用域:作用于函数内的代码环境,就是局部作用域。
var 声明具有局部作用域,var 声明的变量会成为包含它的函数的局部变量。比如,使用 var 在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁。
function fn () {
var msg = '张三' // 局部变量
}
fn()
console.log(msg) // msg is not defined
全局变量
Var 在全局作用域声明的变量会成为全局变量,会成为window 对象的属性(let 、const则不会)
var name = '张三'
console.log(window.name) // 张三
let height = 168
console.log(window.height) // undefined
const weight = '50KG'
console.log(window.weight) // undefined
在声明变量时,省略了 var 关键字,变量也会成为全局变量
function fn () {
msg = '你好' // 全局变量
}
fn()
console.log(msg) // 你好
var声明存在变量提升
使用var声明变量会使得声明的变量自动提升到作用域顶部
// 全局作用域
console.log(age) // undefined
var age = 18 //
==================
上述代码等价于下面:
var age
console.log(age)
age = 18
// 函数(局部)作用域
function fn () {
console.log(age)
var age = 18
}
fn() // undefined
==================
上述代码等价于下面:
function fn () {
var age
console.log(age)
age = 18
}
let 声明
块级作用域
let 声明存在块级作用域,其声明的变量只在 let 命令所在的代码块内有效(const 同样支持块级作用域)
{
let gender = '男'
}
console.log(gender) // gender is not defined
{
const PI = 3.14
}
console.log(PI) // PI is not defined
暂时性死区
let 声明的变量不会在作用域中被提升
console.log(age) // Cannot access 'age' before initialization
let age = 18
不允许重复声明
let 不允许在相同作用域内重复声明同一个变量
let a = 18
let a = 20 // Identifier 'a' has already been declared
function fn () {
let b = 18
let b = 20 // Identifier 'b' has already been declared
}
不能在函数内部重新声明参数
function fn (arg) {
let arg // Identifier 'arg' has already been declared
}
const 声明
const 声明一个只读的常量,一旦声明,常量的值就不能改变
const PI = 3.1415926
PI = 3.14 // Assignment to constant variable.
const 一旦声明常量,就必须立即初始化
const PI // Missing initializer in const declaration
const 本质
const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值)而言,值就保存在变量指向的内存地址中,因此等同于常量。但对于复合类型的数据(主要是对象和数组)而言,变量指向的内存地址保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,这完全不能控制。
高频面试题
var、let、const之间的区别?
区别:
var声明变量可以重复声明,而let不可以重复声明var是不受限于块级的,而 let 是受限于块级var会与 window 相映射(会挂一个属性),而let不与 window 相映射var存在变量提升,可以在声明的上面访问变量,而let有暂存死区,在声明的上面访问变量会报错const声明之后必须赋值,否则会报错const定义不可变的量,改变了就会报错const和let一样不会与 window 相映射、支持块级作用域、在声明的上面访问变量会报错