JavaScript 新旧替换一:变量声明
Posted XXHolic
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 新旧替换一:变量声明相关的知识,希望对你有一定的参考价值。
目录
引子
在工作中,最初接触 ES5 的语法比较多,后来渐渐的接触了新的语法。由于一些原因,需要在不同的项目使用不同的语法。时间长了,发现在写代码的时候,偏向用更加熟悉的旧语法,但感觉这么下去不太妙。于是,就想着针对工作中常用的旧语法,跟可以替换的新语法进行对比,加深印象,然后记录总结一下,有意识的更新相关知识点。
ES5 方式
在 javascript 中,变量可以用来保存任何类型的数据。每个变量只是一个用于保存值的占位符而已。在 ES5 中,使用 var
声明变量,这种声明方式的特点有:
- 声明的变量不赋值,会初始化默认值为
undefined
。
var testVariable;
console.info(‘testVariable=‘,testVariable); // undefined
- 可以一条语句定义多个变量,变量之间用逗号分开。
var name = ‘Tom‘,
age = 15;
- 如果省略
var
声明,则会创建一个全局变量,这样会污染全局变量,这种方式不推荐。 - 用
var
声明的变量会自动添加到最近的环境中,当查找变量的时候,搜索过程是从作用域链的前端开始,向上逐级查询。如果在局部环境中找到了变量,则停止搜索,使用找到的变量。 - 同一作用域内重复声明同一变量时,后声明会覆盖前声明。
var testVariable = ‘123‘;
var testVariable = ‘12‘;
console.info(‘testVariable=‘,testVariable); //12
- 声明的变量会发生“变量提升”,也就是说可以先使用后声明,这种方式不推荐。
console.info(‘testVariable=‘,testVariable); // undefined
var testVariable = 1;
使用 var
声明比较经典的现象是在 for
循环语句中。
function printNum() {
var numArray = [];
for(var i=0;i<5;i++) {
numArray.push(function (){
console.info(i);
})
}
numArray[0]();
}
printNum(); // 5
for
循环中用 var
声明的变量 i
在函数 printNum
作用域中都有效,每次循环执行的语句 console.info(i)
中的 i
和 for
循环中声明的 i
,指向的是同一个 i
,执行完最后一次循环时,i
的值就是 5。
ES2015+ 方式
新增的声明变量方式有:let、const。
let 声明
用法跟 var
类似,这种方式不同的地方有:
- 声明的变量,在
let
所在的代码块内有效。
{
let testLet = 1;
var testVar = 2;
}
console.info(‘testVar=‘,testVar); // 2
console.info(‘testLet=‘,testLet); // Uncaught ReferenceError: testLet is not defined
- 不会“变量提升”,要先声明后使用,否则会报错。
console.info(‘testLet=‘,testLet); // Uncaught ReferenceError: testLet is not defined
let testLet = 1;
这种过早访问 let
声明的引用导致的 ReferenceError
严格说叫做“暂时死亡区”(Temporal Dead Zone,TDZ)错误。这种情况下,使用 typeof
就会有问题。
console.info(typeof testVar);
console.info(typeof testLet);
var testVar = ‘123‘;
var testLet = 123; // Uncaught ReferenceError: testLet is not defined
- 同一作用域内,不允许重复声明同一个变量。
let testLet = 1;
let testLet = ‘123‘; // Uncaught SyntaxError: Identifier ‘testLet‘ has already been declared
同样在 for
循环中使用时:
function printNum() {
var numArray = [];
for(let i=0;i<5;i++) {
numArray.push(function (){
console.info(i);
})
}
numArray[0]();
}
printNum(); // 0
for
循环头部的 let i
为每次循环都重新声明了一个变量 i
。头部的声明是一个作用域,循环体内是另外一个单独的作用域。
for(let i=0;i<2;i++) {
let i = ‘123‘;
console.info(i);
}
// 123
// 123
const 声明
这种形式的声明,是用于创建常量。常量不是对这个值本身的限制,而是对赋值的那个变量的限制。变量实际是指向一个内存地址,const
就对这个内存地址所保存的数据进行了限制。对于简单的数据(例如数值、字符串、布尔值),值就保存在那个内存地址中,就等同于常量。如果复合类型的数据(例如数组和对象),内存地址中保存的就是一个指向实际数据的指针,const
保证的是这个指针固定,这个指针实际指向的内容就不能控制了。
const testConst = [1,2];
testConst.push(3);
console.info(testConst); // [1,2,3]
这种方式的特点有:
- 同
let
一样,所在的代码块内有效。
{
const TEST = "0.618";
}
console.info(TEST); // Uncaught ReferenceError: TEST is not defined
- 不会“变量提升”,要先声明且初始化后才能使用,否则会报错。同样存在“暂时死亡区”。
const K = 1.13198824;
console.info(K);
const TEST;
console.info(TEST);
// SyntaxError: Missing initializer in const declaration
- 同 let 一样,同一作用域内,不允许重复声明同一个变量。
选择那种方式?
在目前的工作中,发现使用 const
的频率非常高,一方面可能是由于使用 react 不可变数据,另一方面是听说 JavaScript 引擎在某些情况下对 const
进行了更好的优化。理论上说,引擎如果了解这个变量的值或类型不会改变,那么它就可以取消某些可能的追踪。实际到底有没有,这没有找到相关的信息。
在 stackoverflow 中也有类似的提问:Const in javascript? When to use it and is it necessary。还有一些文章中的描述,似乎想要用 const
来规范代码行为:必须要初始化。这种规范代码行为的方式感觉很奇怪,写代码很重要的一个功能就是清晰的表达你的意图,不仅仅对自己,也是对未来的维护者或合作者。可能有人觉得到时候如果要改数据,把 const
修改为 let
就可以了。这样也许可以达到目的,那么后来接手的人只要想修改数据,就把 const
修改为 let
,这样子做真的好吗?
从代码的可读性和可理解性上,个人认同的方式是:当你想表明这个变量不会改变时才使用 const
,这样更加合理。
参考资料
以上是关于JavaScript 新旧替换一:变量声明的主要内容,如果未能解决你的问题,请参考以下文章