JavaScript漫谈之深入理解变量

更多内容请关注GitHub

变量是大多数编程语言的基础,并且是要掌握的第一个也是最重要的一个概念。在JavaScript中有许多变量属性以及需要遵守的规则。

一、理解变量

变量是用于存储值的命名容器。在JavaScript中,变量的值可以是任何数据类型,比如numberstringobject等。

ES6之前,声明变量只有一种方式,就是使用关键字var。以下就是使用var声明一个变量并赋值对其进行赋值。

var name = 'sueRimn';

// 变量的值可以是JavaScript中的任何数据类型
var age = 22; 
var friends = [1, 2, 3]; 
var family = {father: 'hui', mother: 'hua'};
var boy = false;
var nothing = null;
  • 变量将数据存储在内存中,之后可以访问和修改这些数据
  • 变量也可以重新分配并给定一个新值

下面演示了如何将数据存储到变量中,然后进行更新:

var name = 'sueRimn';
name = '八至';
console.log(name); // '八至'

二、命名变量

变量名在JavaScript中称为标识符。命名标识符在JavaScript中有一定的规则,如下:

  • 变量名只能由字母、数字、$符号以及下划线组成
  • 变量名不能包含任何空白字符(制表符或空格)
  • 变量名的首字符不能为数字
  • 个别保留字和关键字不能用作变量的名称
  • 变量名区分大小写

另外还有一些非强制但建议使用的规则可以使你的代码更具有规则、可读性以及二次维护性:

  • 变量名使用驼峰命名法
  • const声明的常量使用大写
  • 尽量使用let声明变量而不是var

在JavaScript中,使用三个关键字声明变量:

  • var:声明全局变量
  • let:声明局部变量
  • const:声明局部常量,不可更改值

下面讲讲述这三种声明方式的区别。

三、声明变量

变量声明,无论发生在何处,都在执行任何代码之前进行处理。使用varletconst声明的区别是基于作用域、提升以及重新分配定义的。

(1)使用var声明变量

1)声明变量

MDN这样解释:用 var 声明的变量的作用域是它当前的执行上下文,对于任何函数之外声明的变量,它要么是封闭函数,要么是全局的。如果您重新声明一个JavaScript变量,它将不会丢失自己的值。

为未声明的变量赋值时会悄咪咪地将其创建为全局变量(它将成为全局对象的属性)。

声明变量和未声明变量的区别如下:

  • 声明的变量局限于声明时所处的执行上下文,未声明的变量是全局的;
  • 声明的变量在执行任何代码之前被创建,未声明变量在分配给它们的代码执行之前不存在
  • 声明的变量是其执行上下文(函数或全局)的不可配置属性,未声明变量是可配置的(如:可删除)

因为没有声明的变量在严格模式下一定会报错,所以强烈建议不管在函数作用域还是全局作用域内,一定要声明变量

2)存在提升

因为变量声明是在执行任何代码之前执行的,所以在代码中的任何位置声明变量都是在代码顶部声明变量。这也意味着变量可以在声明之前出现。这种行为称为”变量提升”,因为变量声明总是被自动移动到函数或全局代码的顶部。当变量未赋值时,会报undefined错误,即未定义。
JavaScript漫谈之深入理解变量

上面代码可见name变量在声明前赋值了, 但是没有报错,那是因为自动变量提升,其实其执行顺序是这样的:

var name;
name = '八至';

JavaScript漫谈之深入理解变量

而以上代码这种情况就是,在声明之前未赋值的变量出现了,显示undefined,这是因为JavaScript仅提升声明,不提升初始化,如果先使用变量,在声明并初始化,变量的值将是undefined,其执行顺序是这样的:

var age;
console.log(age);

建议不管是在函数内部还是全局作用域,变量声明都应该在代码顶部首先进行。

3)var声明的变量可重新分配值

使用var声明的变量可以重新被声明和重新被分配值。

var name = 'sueRimn';
name = '八至'; // 重新分配值
var name = '小九'; // 重新声明
console.log(name); // 小九

(2)使用let声明变量

let声明一个块级作用域的本地变量,并且可将其初始化。

let name = 'sueRimn';

1)声明变量

let允许声明一个块级作用域的变量、语句或者表达式。与 var关键字不同的是, var声明的变量是属于全局或者整个封闭函数块的。

JavaScript漫谈之深入理解变量

JavaScript漫谈之深入理解变量

看到上面代码的区别了吗,let声明的变量属于块级作用域({})的,if语句中属于块级作用域,var不局限于块级作用域,变量被从新赋值,所以打印的都是最新值;而let声明的变量局限于此,打印的是属于自己块级中的赋的值。

2) 不存在提升

let声明的变量是不存在变量提升的:

JavaScript漫谈之深入理解变量

这是因为在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区“。

如果使用typeof操作符检测处于暂存死区的变量,会抛出ReferenceError的错误:

JavaScript漫谈之深入理解变量

3)不允许重复声明

let声明的变量可以重新赋值,但是不能重新声明,重新声明会抛出SyntaxError的错误:

JavaScript漫谈之深入理解变量
JavaScript漫谈之深入理解变量

(3)使用const声明常量

1)声明

const声明的常量属于块级作用域,常量的值不能重新赋值,并且不能重新声明。

const AGE = 22;

const声明创建一个只读的值。但这并不意味着它所持有的值是不可变的,只是说变量标识符不能重新分配。

不可重新赋值

JavaScript漫谈之深入理解变量

不可重新声明

JavaScript漫谈之深入理解变量

声明常量的时候必须初始化

JavaScript漫谈之深入理解变量

2)不存在提升

const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。

(4)区别

关键字变量作用域存在提升能否重新声明能否重新分配值
var函数作用域YESYESYES
let块级作用域NOYESNO
const块级作用域NONONO

四、总结

本文中,讲述变量是什么、命名变量的规则以及声明变量的方式。知道了声明变量的三个关键字,并讲述了三种不同声明方式的区别以及变量所存在的作用域和是否存在提升,为了更好的执行JavaScript脚本,建议尽量多使用let以及const

相关推荐