JavaScript 变量
变量用来储存信息,使用赋值操作符 =
为变量绑定数据(数据保存到与该变量相关联的内存区域),数据通过变量名进行存取操作。
声明变量
在使用变量前应该先定义/声明它(虽然在非严格模式下简单地通过赋值可以创建一个变量,但并不推荐)。使用关键字 推荐使用关键字 var
创建变量let
或 const
(而非 var
)声明变量。
- 使用
let
声明的变量可以重新赋值(但是不能在同一作用域内重新声明)。 - 使用
const
声明的变量必须赋初始值,且无法重新赋值(一般用于创建常量)。const
是声明变量最严格的方式,当标识符在程序的整个生命周期内都不会改变,建议使用const
声明变量(还可以将变量名全大写),以使代码阅读性更强,传递更准确的含义。
连续声明好几个变量,在开头使用一个声明关键字,而多个变量用逗号 ,
分隔(最后用别忘了使用 ;
标记语句结束),习惯将一个变量置于一行,这样声明有点长,但更容易阅读。
// 声明多个变量,变量之间用逗号分隔,并各变量占一行便于阅读
let user = 'John',
age,
message;
Warning
推荐使用 let
或 const
而不是 var
,因为前两者可以让变量陷入暂时性死区,避免浏览器解析 JavaScript 时将变量提升到函数作用域顶部引起不可预计的错误。
旧式变量声明
使用「旧式」的关键字 var
声明的变量没有块级作用域,只有函数作用域和全局作用域。
而且声明被 🎬 提升 hoisting/raising 到函数开头处理(如果是全局变量就会在脚本启动时进行处理),即 var
声明的变量会在函数开头被定义,与它在代码中定义的位置无关。
function sayHi() {
phrase = "Hello";
alert(phrase);
var phrase; // 该声明会被自动提升到函数顶部先进行处理
}
sayHi();
Warning
使用关键字 var
定义的变量,其声明会提升(此时的变量值为 undefined
),但赋值操作并不会。因为所有 var
声明都是在函数开头处理的,我们可以在任何地方引用它们,但是在它们被赋值之前变量值都是 undefined
。
function sayHi() {
alert(phrase); // undefined
var phrase = "Hello";
alert(phrase); // Hello
}
sayHi();
Tip
在旧式的脚本中会使用一种称为 立即调用函数表达式 IIFE 技术来「修复」使用关键字 var
声明的变量所造成的副作用。
变量作用域
作用域是限制变量或函数的可访问的区域。如果在代码块 {...}
内声明了一个变量,那么这个变量只在该代码块内可见,该限制对于条件语句、循环语句、函数内定义的变量都适用。
{
// 用局部变量完成一些不应该被外面访问的工作
let message = "Hello";
alert(message); // Hello
}
alert(message); // Error: message is not defined
for (let i = 0; i < 3; i++) {
// 变量 i 仅在这个 for 循环的内部可见
alert(i); // 0,然后是 1,然后是 2
}
alert(i); // Error, no such variable
Tip
从视觉上看,let i
位于 {...}
之外,但是 for
是特殊的结构,在判断语句中的变量声明被视为块的一部分。
Warning
只有使用关键字 let
或 const
声明的变量才遵循代码块作用域的限制,使用旧关键字 var
声明的变量则只有全局作用域和函数作用域之分,如在条件语句或循环语句中声明的变量在代码块外依然可以访问。
利用变量作用域的限制,可以使用「空」的代码块将变量隔离到「局部作用域」中。如果在 Web 浏览器中所有脚本都共享同一个全局环境,当我们在一个脚本中创建一个全局变量,对于其他脚本来说它也是可用的,要是存在两个脚本使用同一个变量就会产生冲突报错,此时如果适用代码块 {}
将大部分变量包括就可以避免这种问题。
// 显示 message
let message = "Hello";
alert(message);
// 显示另一个 message
let message = "Goodbye"; // Error: variable already declared,同一词法环境中不可对同一变量进行两次声明
alert(message);
Tip
代码块有其自身的词法环境,块之外(或另一个脚本内)的代码访问不到代码块内的变量。
变量名
变量名应尽量可以准确、简洁地描述数据内容,其遵循 小驼峰命名法 camelCase(第一个单词小写,所有后续单词都首字母大写)规则。
变量名只能由字母、数字、符号 $
和 _
构成,首字符不能为数字,且区分大小写。
Warning
连字符 -
不允许用于变量命名
let totalAfterTax = 53.03; // 如果变量名由多个单词组成,使用驼峰命名法
let tip = 8; // 如果变量名是一个单词,则使用全小写字母
let $ = 1; // 使用 "$" 声明一个变量
let _ = 2; // 现在用 "_" 声明一个变量
常量
常数是指在执行之前就已知了或在执行期间被「计算」出来不会再改变的值,即一般通过 hard-coded 硬编码生成的值用大写命名的常量来存储;而执行「计算」出来的值(虽然它还是有一定的可变性,随着代码的执行情况而改变)某种意义上赋予初始值后就不会变化。
常量一个普遍用法是作为别名,以便记住那些在执行之前就已知(不改变)的难以记住的值。硬编码产生的常量一般使用大写字母和下划线来命名,而计算得出的初始值的常量则使用小驼峰命名的。
如用常量表示 web 颜色(十六进制)的别名。
const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
// 当我们需要一个该颜色,可以基于其变量(别名)快速获得
let color = COLOR_ORANGE;
Tip
使用关键字 const
声明的常量之后不可修改,否则浏览器会在控制台输出错误。但是如果将对象作为值,由于它赋值时传递的是引用,所以修改对象属性并不会报错,只有修改常量对于对象的引用才会报错。
const family = {
mom: '老媽',
me: '小明',
sister: '小橙'
};
family.father = '爸爸'; // 修改对象属性并不会报错
console.log(family);
family = {}; // 修改变量的引用,会报错