zoukankan      html  css  js  c++  java
  • typescript let和const区别

    全局声明

    var声明在函数体外,所声明的变量为全局变量。

    var name = "张三";
    

    var所声明的全局变量会作为window的一个属性,可以使用"."来引用。如上例的name引用:

    console.log(window.name)
    

    注意:非严格模式下,声明在函数体内的变量,把声明语句的var去掉,那么所声明的变量也是全局变量。

    作用域

    var变量声明的最大特点是它的作用域为声明语句所在的最近函数体内。

    示例:

    function f() {
        var message = "Hello, world!";
    
        return message;
    }
    

    var所声明的message变量的作用域范围就是在函数f内。

    var声明变量的作用域为函数体的全部,隐含着两个主要问题:变量提升和循环内变量共享。

    变量提升

    变量提升:JavaScript会把函数内的变量声明提升到函数的最顶部。

    示例:

    function(){
        var a='a';
        var b='b';
        var c='c';
    }
    

    等同于

    function(){
        var a,b,c;
        a='a';
        b='b';
        c='c';
    }
    

    这样看是貌似没有问题,想一下下面的例子输出结果:

    var message='message 1';
    (function(){
        console.log(message)
        var message ='message 2';
    })()
    

    很多人可能会认为控制台输出的结果是message 1。执行一下会发现,输出的结果为undefined。这是因为变量提升了。

    上面的例子实际等同于

    var message='message 1';
    (function(){
        var message;
        console.log(message)
        message ='message 2';
    })()
    

    变量提升有它的优势,但也常常给我们带来一些难以发现的bug。

    循环内变量共享

    直接看示例:

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

    我们期待的输出结果为依次为0,1,2,3,4,5,6,7,8,9,而实际输出结果都为10。这是因为在循环内共享了变量i,i自增到10结束setTimeOut()里的函数还没有调用,当调用函数时,i值为10,所以输出的结果都为10。

    为了解决循环内变量共享,可以考虑使用IIFE。

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

    重复声明

    在上面的例子

    var message='message 1';
    (function(){
        console.log(message)
        var message ='message 2';
    })()
    

    message是允许重复声明的,重复声明的变量会覆盖之前声明的变量。

    let变量声明

    let是ES6新增的特性,也是为了解决var变量声明所存在的一些问题,可以说let是更完美的var。

    基本用法

    let varName = 变量值;

    示例:

    let name = "张三";
    

    这是和var声明变量类似。

    注意:如果let变量声明在全局,它并不会像var声明的变量一样成为window的一个属性。

    作用域

    let变量声明和var最大的不同点就是变量的作用域不一样。var为函数作用域,而let变量声明的为块作用域(block-scoping)。

    块作用域会把声明的变量限定在代码块(如使用{}括起来的代码库)或者for循环内,而不是整个函数体。

    function f(input: boolean) {
        let a = 100;
    
        if (input) {
            let b = a + 1;
            return b;
        }
        // 出错: 'b'属于上面的代码块定义的,在代码块外不能使用。
        return b;
    }
    

    let声明的变量不允许在声明前使用,这样解决了var变量提升引起的问题。

    (function(){
      console.log(message);    //此处会报错,Uncaught ReferenceError: message is not defined
      let message ='my message';
    })()
    

    对于循环内的变量,每次循环都会是捕获值的副本作为运算,而不是共享同一个值,解决了var循环内共享变量的问题。所以前面for循环的例子只需把var改为let即可:

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

    重复声明

    let是不允许在同一作用域内重复声明,重复声明会报error: can't re-declare 'x' in the same scope。

    function f(x) {
        let x = 100; // error: interferes with parameter declaration
    }
    
    function g() {
        let x = 100;
        var x = 100; // error: can't have both declarations of 'x'
    }
    

    const变量声明

    const变量声明和let类似,但如它的名字所寓意,它定义的是常量,包含了两层意思:

    1. 声明的的变量不能被重复赋值
    2. const声明变量是必须立刻赋值
    const numLivesForCat = 9;
    numLivesForCat = 10;  //重复赋值,错误
    
    const name;  //错误,声明时没有赋值
    name = "张三";  
    

    对于const声明的对象,对象本身是不能被赋值覆盖,但是对象的可修改属性是允许被修改值的。

    const numLivesForCat = 9;
    const kitty = {
        name: "Aurora",
        numLives: numLivesForCat,
    }
    
    // Error
    kitty = {
        name: "Danielle",
        numLives: numLivesForCat
    };
    
    // all "okay"
    kitty.name = "Rory";
    kitty.name = "Kitty";
    kitty.name = "Cat";
    kitty.numLives--;

    转自:https://majing.io/posts/10000000721104
  • 相关阅读:
    gym 101480 Problem C: Cow Confinement 题解
    Uva 1072 Huffman Codes 题解
    NERC 2015 Hypercube 题解
    ACM ICPC 2017 WF Problem J Son of Pipe Stream题解
    CF Round # 295 (Div. 1)题解
    CF 1444 D Rectangular Polyline 题解
    BZOJ3308 九月的咖啡店
    BZOJ4025 二分图
    BZOJ4000 [TJOI2015]棋盘
    BZOJ3999 [TJOI2015]旅游
  • 原文地址:https://www.cnblogs.com/xyyou/p/11673095.html
Copyright © 2011-2022 走看看