TS基础篇3:变量

第一 : var

1、var声明有些奇怪的作用域规则:
-----var声明可以在包含它的函数,模块,命名空间或全局作用域内部任何位置被访问

function f(shouldInitialize: boolean) {
    if (shouldInitialize) {
        var x = 10;
    }
    return x;
}
f(true);    // return '10'
f(false);   // return 'undefined'

可能引发的错误:多次声明同一个变量并不会报错,可能在代码审查时漏掉,引发无穷的麻烦

function sumMatrix(matrix: number[][]) {
    var sum = 0;
    for (var i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (var i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

问题:里层的for循环会覆盖变量i,因为所有i都引用相同的函数作用域内的变量
------这个版本的循环不能得到正确的结果


2、捕获变量的怪异之处

for (var i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i); }, 100 * i);
}

输出:
10 10 10 10 10 10 10 10 10 10 10 

原因:setTimeout在若干毫秒后执行一个函数,并且是在for循环结束后。 for循环结束后,i的值为10。 所以当函数被调用的时候,它会打印出 10!

解决办法:
使用立即执行的函数表达式(IIFE)来捕获每次迭代时i的值

for (var i = 0; i < 10; i++) {
    (function(i) {
        setTimeout(function() { console.log(i); }, 100 * i);
    })(i);
}

第二:let

let声明使用的是词法作用域或块作用域
1、变量在包含它们的块或for循环之外是不能访问的

function f(input: boolean) {
    if (input) {
        let b =  1;
        return b;
    }
    // Error: 'b' doesn't exist here
    return b;
}

2、变量不能在被声明之前读或写。
---- 虽然这些变量始终“存在”于它们的作用域里,但在直到声明它的代码之前的区域都属于 暂时性死区

function foo() {
    return a;
}
// 不能在'a'被声明前调用'foo'
foo();
let a;

3、变量不能重定义
@var定义的变量是可以重定义,但之后得到最后一个

let x = 10;
let x = 20; // 错误,不能在1个作用域里多次声明`x`

4、变量屏蔽
屏蔽:在一个嵌套作用域里引入一个新名字的行为

function sumMatrix(matrix: number[][]) {
    let sum = 0;
    for (let i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (let i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

这个版本的循环能得到正确的结果,因为内层循环的i可以屏蔽掉外层循环的i。


5、let声明出现在循环体里时拥有完全不同的行为
原理:不仅是在循环里引入了一个新的变量环境,而是针对 每次迭代都会创建这样一个新作用域。** 这就是我们在使用立即执行的函数表达式时做的事**

for (let i = 0; i < 10 ; i++) {
    setTimeout(function() {console.log(i); }, 100 * i);
}
输出: 0 1 2 3 4 5 6 7 8 9

第三 : const

1、与let声明相似,但被赋值后不能再改(常量)
2、实际上const变量的内部状态是可修改的。 幸运的是,TypeScript允许你将对象的成员设置成只读的。


注意: let vs const

最小特权原则:所有变量除了你计划去修改的都应该使用const

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 9,700评论 0 13
  • let 命令 块级作用域 const 命令 顶层对象的属性 global 对象 let 命令 基本用法 ES6 新...
    嘉奇呦_nice阅读 5,536评论 0 2
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 14,749评论 0 38
  • 什么时候开始努力成为更好的自己,最好是十年前,其次是现在。 1.知道你想要什么 转眼间快大三了,我用了两年的浑浑噩...
    赵小翀阅读 4,177评论 24 36
  • 樊迟问知,子曰:“务民之义,敬鬼神而远之,可谓知矣。”问仁,曰:“仁者先难而后获,可谓仁矣。” 敬而远之是一种人生...
    碧空远影601阅读 4,496评论 0 2

友情链接更多精彩内容