JavaScript笔记(自用)——03变量(varletconst)
Posted 蓝Builing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript笔记(自用)——03变量(varletconst)相关的知识,希望对你有一定的参考价值。
javascript笔记(自用)——03变量
笔记均参考自JavaScript高级程序设计
ECMAScript变量可以用于保存任何类型的数据。有三个关键字可以声明变量:var、const和let。(let和const只能在ES6以后本版使用)
var 关键字
定义变量可以使用 var 操作符(var是一个关键字),后跟一个变量名:
var messagr; //声明了一个名为message的变量,可保存任意类型数据
//不初始化的情况下,会保存一个特殊的值undefind
初始化变量:
var message="hi";
赋值
message=100;
var声明作用域
在function外部定义为全局变量
在function内部定义为局部变量
没有var直接给标识符赋值为全局变量
<script>
var message="hi"; //全局变量
function test(){
b = "我是全局变量b"; //全局变量,但不推荐,严格模式下会抛出异常
var a=3; //局部变量
console.log(a); //3
}
console.log(message); //“hi”
console.log(b); //“我是全局变量b”
console.log(a); //出错!
</script>
定义多个变量可以在一条语句中用逗号分隔每个变量(及初始化):
var snake="si",
age=18,
message="haha";
var声明提升
提升是指把所有的变量声明都拉到函数作用域的顶部。
function foo(){
console.log(age);
var age=26;
}
foo(); //undefined
等价于
function foo(){
var age;
console.log(age);
gae=26;
}
foo(); //undefined
let声明
let和var的作用差不多,但有非常重要的区别:
let声明的范围是块作用域,var声明的范围是函数作用域
if(true){
var name='haha';
console.log(name); //haha
}
console.log(name); //haha
if(true){
let age=18;
console.log(age); //18
}
console.log(age); //ReferenceError: age is not defined(age没有定义)
这里age变量之所以不能在if块外部被引用,是因为它的作用域仅限于该块内部
块作用域是函数作用域的子集,因此适用于var的作用域限制也同样适用于let
let不允许同一个块作用域中出现冗余声明。这样会导致报错:
var name;
var name;
let age;
let age; //SyntaxError: Identifier 'age' has already been declared
//即 SyntaxError: 标识符age已声明过了
JavaScript引擎会记录用于变量声明的标识符及其所在的块级作用域,因此嵌套使用相同的标识符不会报错。因为同一个块中没有重复声明
var name='lan';
console.log(name); //lan
if(true){
var name='jing';
console.log(name); //jing
}
let age=30;
console.log(age); //30
if(true){
let age=18;
console.log(age); //18
}
对声明冗余的变量不会因为混用let和var受影响。这两个关键字声明的并不是同类型的变量,它们只是指出变量在相关作用域如何存在。
var num1;
let num1; //SyntaxError
暂时性死区
let与var的另一个重要区别就是let声明的变量不会在作用域中被提升
在解析代码时,javascript引擎也会在意出现在块后面的let声明,在此之前不能以任何方式来引用未声明的变量。
在let被声明之前执行的瞬间被称为“暂时性死区”
,在此阶段引用任何后面才声明的变量都会抛出ReferenceError
//name会被提升
console.log(name); //undefined
var name='lan';
//age不会被提升
console.log(age); //ReferenceError: age is not defined
let age=18;
全局声明
使用let在全局作用域中声明的变量不会成为window对象的属性
(var声明的变量则会)
*注意:let声明任然是在全局作用域中发生的
,相应的变量会在页面的生命周期内存续。为了避免SyntaxError,必须确保页面不会重复声明同一个变量
。
var name='lan';
console.log(window.name); //lan
let age=26;
console.log(window.age); //undefined
for循环中的let声明
在let出现之前,for循环定义的迭代变量会渗透到循环体外部
for(var i=0;i<5;++i){
//循环逻辑
}
console.log(i); //5
let之后,这个问题就消失了。(作用域)
for(let i=0;i<5;++i){
//循环逻辑
}
console.log(i); //ReferenceError:i没有定义
对迭代变量的奇特声明和修改:
for(var i=0;i<5;++i){
setTimeout(()=>console.log(i),0);
}
//输出为:5,5,5,5,5
-
在退出循环时,迭代变量保存的是导致循环退出的值。在之后的执行超时逻辑时,所有的i都是同一个变量。
-
使用let声明迭代变量时,JavaScript引擎在后台会为每个迭代循环声明一个新的迭代变量。
for(var i=0;i<5;++i){ setTimeout(()=>console.log(i),0); } //输出为:0,1,2,3,4
const声明
-
const的行为与let基本相同。
-
const声明变量时
必须同时初始化变量
。 -
试更改const声明的变量会导致运行时错误.。
const age=15; age=18; //TypeError:给常量赋值 //const也不允许重复声明 const name='lan'; const name='jing'; //SyntaxError //const声明的作用域也是块 const name='lan'; if(true){ const name='jing'; } console.log(name); //lan
const声明的变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制。
const person={};
person.name='lan'; //ok
-
javascript引擎会未for循环中的let声明分别建立独立的变量实例,const与let变量相似,也不能const来声明迭代变量(迭代变量会自增):
for(const i=0;i<10;++i); //TypeError:给常量赋值
-
可以只用const声明一个不被修改的for循环变量。即:每次迭代只是创建一个新变量。
let i =0; for(const j=7;i<5;++i){ console.log(j); } //7,7,7,7,7
声明风格建议
- 不使用var
只使用let和const有助于提升代码质量,因为变量有明确的作用域、声明位置、不变的值
。 - const优先,let次之
- 使用const声明可以让浏览器运行时强制保持变量不变。
- 也可以让静态代码分析工具提前发现不合法的赋值操作。
- 有利于后期维护。
以上是关于JavaScript笔记(自用)——03变量(varletconst)的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript笔记(自用)——01什么是JavaScript
JavaScript笔记(自用)——01什么是JavaScript