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

  1. - 函数内变量声明会提升到函数作用域顶部
  2. ```typescript
  3. function fn3(flag: boolean) {
  4. // 严格模式下 var变量未声明会报错 非严格模式下是undefined
  5. // tsconfig.json配置了 "strict": true,必须声明
  6. var a: number = 20;
  7. if (flag) {
  8. var a = 10;
  9. return a;
  10. }
  11. return a;
  12. }
  13. console.log(fn3(true)); // 10
  14. console.log(fn3(false)); // 20
  • 双重循环计算矩阵和,内外循环需要不同变量名声明
    1. type Matrix = number[][];
    2. function sumMatrix(matrix: Matrix) {
    3. var sum = 0;
    4. for (var i = 0; i < matrix.length; i++) {
    5. const item = matrix[i];
    6. // 因为使用的是var,所以需要使用不同和i不同的变量名
    7. // 如果是使用let,k也可以替换成i,不过为了代码的可读性,一般也会使用其他名称
    8. for (var k = 0; k < item.length; k++) {
    9. sum += item[k];
    10. }
    11. }
    12. return sum;
    13. }
    14. var matrix = [
    15. [1, 2],
    16. [3, 4],
    17. ];
    18. console.log(sumMatrix(matrix)); // 10
  • 循环内使用定时器:
    1. function fn4() {
    2. for (var i = 0; i < 10; i++) {
    3. setTimeout(function () {
    4. console.log(i);
    5. }, 0);
    6. }
    7. }
    8. // var是函数作用域,当调用栈执行完for循环,i=10
    9. // event loop开始执行定时器,作用域内的i已经为10

    解决方法 :
  1. 使用闭包形成函数作用域
  2. 使用 let 形成块作用域

let

  • 块作用域,不会变量提升到函数顶部
  • 使用前需要声明,否则会报错
    1. function fn1(flag: boolean) {
    2. // 使用前需要声明 ,如果没有声明,访问不到判断语句内的变量,会报错
    3. let a;
    4. if (flag) {
    5. let a = 20;
    6. return a;
    7. }
    8. return a;
    9. }
    10. console.log(fn1(false));
  • try catch 外访问不到里面的变量
    1. try {
    2. let a = 10;
    3. } catch (error) {
    4. console.log(error);
    5. }
    6. // console.log(a) 这里访问不到a
  • 暂时性死区,声明后才能使用,同一作用域下不能重复声明
  • 注意:var 在声明前可以使用,tsc xxx.ts —target es2015 编译成 es2015 后,会把 var 转 成 let,会导致报错

const

与 let 区别:const 声明后不能在重新赋值