变量声明
var
首先,我们来看一个例子
for(var i = 0;i<10;i++){
setTimeout(function(){
console.log(i);
},1000);
};
// 10 10 10 ... 10
有经验的读者或者直接运行代码后,我们知道控制台在1s后会输出10次同样的数字10;这明显与我们想要的从0开始依次输出到9不一致。 如果我们想要依然用
var
来声明i
并想得到所要的结果,就要像下面这样做:
for(var i = 0;i<10;i++){
(function(i){
setTimeout(function(){
console.log(i);
},1000);
})(i);
};
// 0 1 2 3 ... 9
可以看出上面为了实现想要的效果,用到了立即执行函数(IIFE)。 用到立即执行函数,解决的其实就是函数作用域的问题。
为了解决var
声明的变量的作用域问题,ES6
的创建了let
和const
两个工具来声明变量。而typescript
同样支持这两个声明的工具
let
同样的我们来看一个例子: ```javascript var a = 1; var a = 10; console.log(a); // 10
let b = 1; let b = 11; console.log(b); // 报错
> 同样声明同一个变量,var声明多次,后面的声明会覆盖前面声明;而let重复声明同一个变量则会报错。
> 第二个例子:
> ```javascript
function foo() {
console.log(a)
}
foo();
var a = 10;
// undefined
function foo() { console.log(a) } // 不能在'a'被声明前调用'foo' // 运行时应该抛出错误 foo(); let a = 10; // a is not defined
造成这样的结果是变量在foo()函数执行之后声明,但又因为var声明的变量会有变量提升,即会先把var声明的变量a提升到函数执行的顶部,但此时并没有赋值,所以foo函数里面读取到的只是声明了的a,还没有被赋值,所以是undefined; 而let声明的变量并没有变量提升,在foo()执行的时候函数体内的a被没有被声明,所以会报错
a is not defined
let声明的变量除了不能被重复声明和没有变量提升的特点外,还拥有两个跟var声明的变量一样的特点:可被重复赋值(不是重复被声明)和拥有块级作用域。 所谓块级作用域:即
let
声明的变量所在的区域被称作块,这个变量会被“锁住”在所在的区域内(块内),这个被声明的变量都可以被访问到,而在区域之外(块外)就不能被访问到。 如:function foo() { var a = 10; } console.log(a); // 10
// 块级作用域 function foo() { let a = 10; } console.log(a); // 报错信息:a is not defined
// 重复赋值 function foo() { let a = 10; a = 100; console.log(a); }; foo(); // 100
const
const
是let
的加强型声明变量的工具,除了拥有let
一样的块级作用域外,被加强的地方在于const
声明的变量不能被重复赋值,其他功能跟let
一样。const a = 10; function test(flag){ if(flag){ a = 11; } console.log(a); }; test(true); // 报错信息:Assignment to constant variable. // ############################ let a = 10; function test(flag){ if(flag){ a = 11; } console.log(a); }; test(true); // 11