var
- 闭包:作用域寻找规则:会在函数声明的地方查找 ```typescript // 闭包1 function fn() { var a = 10; return function (b: number) { return a + b; }; }
var a = 20; const fn2 = fn(); console.log(fn2(2)); //12
- 函数内变量声明会提升到函数作用域顶部```typescriptfunction fn3(flag: boolean) {// 严格模式下 var变量未声明会报错 非严格模式下是undefined// tsconfig.json配置了 "strict": true,必须声明var a: number = 20;if (flag) {var a = 10;return a;}return a;}console.log(fn3(true)); // 10console.log(fn3(false)); // 20
- 双重循环计算矩阵和,内外循环需要不同变量名声明
type Matrix = number[][];function sumMatrix(matrix: Matrix) {var sum = 0;for (var i = 0; i < matrix.length; i++) {const item = matrix[i];// 因为使用的是var,所以需要使用不同和i不同的变量名// 如果是使用let,k也可以替换成i,不过为了代码的可读性,一般也会使用其他名称for (var k = 0; k < item.length; k++) {sum += item[k];}}return sum;}var matrix = [[1, 2],[3, 4],];console.log(sumMatrix(matrix)); // 10
- 循环内使用定时器:
function fn4() {for (var i = 0; i < 10; i++) {setTimeout(function () {console.log(i);}, 0);}}// var是函数作用域,当调用栈执行完for循环,i=10// event loop开始执行定时器,作用域内的i已经为10
解决方法 :
- 使用闭包形成函数作用域
- 使用 let 形成块作用域
let
- 块作用域,不会变量提升到函数顶部
- 使用前需要声明,否则会报错
function fn1(flag: boolean) {// 使用前需要声明 ,如果没有声明,访问不到判断语句内的变量,会报错let a;if (flag) {let a = 20;return a;}return a;}console.log(fn1(false));
- try catch 外访问不到里面的变量
try {let a = 10;} catch (error) {console.log(error);}// console.log(a) 这里访问不到a
- 暂时性死区,声明后才能使用,同一作用域下不能重复声明
- 注意:var 在声明前可以使用,tsc xxx.ts —target es2015 编译成 es2015 后,会把 var 转 成 let,会导致报错
const
与 let 区别:const 声明后不能在重新赋值
