JavaScript-变量声明

225 阅读4分钟

JavaScript是一门弱类型语言,可以不用事先声明而直接使用,虽然这种方式方便简洁,但是很容易引起变量命名方面的错误,容易造成全局变量污染,因此不建议这样做。在JavaScript中,变量的声明有三种方式,分别是 varletconst,其中,var 在 ECMAScript 的所有版本中都可以使用,letconst是ES6新增的语法,只能在 ECMAScript 6 及更晚的版本中使用,下面笔者就来简单的介绍下这三种变量声明的方式。

变量

在此之前,我们需要了解变量是什么,从字面意思来说,变量就是数值可以发生变化的量;从编程角度来讲,变量就是计算机中用来存储数据的容器,其本质就是程序在内存中申请的一块用来存放数据的小空间。

在JavaScript 中的变量是松散类型(弱类型)的,所谓松散类型就是用来保存任何类型的数据,在定义变量的时候不需要指定变量的数据类型。

变量的命名规范

  1. 首字母必须是字母、下划线(-)或者美元符号($)。
  2. 其他字母可以是下划线(_)、美元符号($)、字母或者数字。
  3. 一般采用驼峰法:第一个字母小写,其余有意义的单词首字母大写。
  4. 变量名是区分大小写的,不能是关键字或保留字。

JavaScript的关键字(保留字)

ECMA-262 第 6 版规定的所 有关键字如下:

关键字.png

var 声明

局部作用域

作用域概述:变量起作用(可被访问)的范围。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了变量名冲突。

全局作用域:作用于所有代码执行的环境;局部作用域:作用于函数内的代码环境,就是局部作用域。

var 声明具有局部作用域,var 声明的变量会成为包含它的函数的局部变量。比如,使用 var 在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁。

function fn () {
  var msg = '张三' // 局部变量
}
fn()
console.log(msg)  // msg is not defined

全局变量

Var 在全局作用域声明的变量会成为全局变量,会成为window 对象的属性(letconst则不会)

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 定义不可变的量,改变了就会报错
  • constlet 一样不会与 window 相映射、支持块级作用域、在声明的上面访问变量会报错