美文网首页前端
js变量详解

js变量详解

作者: sanyer | 来源:发表于2021-09-27 09:25 被阅读0次

    JavaScript 变量是松散类型的,而且变量不过就是特定时间点一个特定值的名称而已。由于没有规则定义变量必须包含什么数据类型,变量的值和数据类型在脚本生命期内可以改变。

    有 3 个关键字可以声明变量:var、const 和 let。其中,var 在 ES 的所有版本中都可以使用,而 const 和 let 只能在 ES6 及更晚的版本中使用。

    1、var 关键字

    要定义变量,可以使用 var 操作符(注意 var 是一个关键字),后跟变量名(即标识符,如前所述):

    var message;

    不初始化的情况下,变量会保存一个特殊值 undefined。

    1. var 声明作用域

    使用 var 操作符定义的变量会成为包含它的函数的局部变量。省略 var 操作符,可以创建一个全局变量。

    function test() { 
     var message = "hi"; // 局部变量
     name = "xiaoming"; // 全局变量
    } 
    test(); 
    console.log(message); // 出错!
    console.log(name); // "xiaoming"
    

    使用关键字声明的称为显式声明,未使用任何关键字声明的称为隐式声明

    1. var 声明提升

    var 声明的变量会自动提升到函数作用域顶部:

    function foo() {
      console.log(age);
      var age = 26;
    }
    foo(); // undefined
    

    2、let 声明

    let 跟 var 的作用差不多,但有着非常重要的区别。最明显的区别是,let 声明的范围是块作用域,而 var 声明的范围是函数作用域。

    if (true) { 
     var name = 'Matt'; 
     console.log(name); // Matt 
    } 
    console.log(name); // Matt
    
    if (true) { 
     let age = 26; 
     console.log(age); // 26 
    } 
    console.log(age); // ReferenceError: age 没有定义
    

    let 也不允许同一个块作用域中出现冗余声明。

    1. 暂时性死区

    let 与 var 的另一个重要的区别,就是 let 声明的变量不会在作用域中被提升。

    // name 会被提升
    console.log(name); // undefined 
    var name = 'Matt'; 
    // age 不会被提升
    console.log(age); // ReferenceError:age 没有定义
    let age = 26; 
    

    在解析代码时,JavaScript 引擎也会注意出现在块后面的 let 声明,只不过在此之前不能以任何方式来引用未声明的变量。在 let 声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出 ReferenceError

    1. 全局声明

    与 var 关键字不同,使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)

    var name = 'Matt'; 
    console.log(window.name); // 'Matt' 
    let age = 26; 
    console.log(window.age); // undefined
    
    1. 条件声明
    <script> 
     var name = 'Nicholas'; 
     let age = 26; 
    </script> 
    <script> 
     // 假设脚本不确定页面中是否已经声明了同名变量
     // 那它可以假设还没有声明过
     var name = 'Matt'; 
     // 这里没问题,因为可以被作为一个提升声明来处理
     // 不需要检查之前是否声明过同名变量
     let age = 36; 
     // 如果 age 之前声明过,这里会报错
    </script>
    
    1. for 循环中的 let 声明

    在 let 出现之前,for 循环定义的迭代变量会渗透到循环体外部:

    for (var i = 0; i < 5; ++i) { 
     // 循环逻辑 
    } 
    console.log(i); // 5
    

    改成使用 let 之后,这个问题就消失了,因为迭代变量的作用域仅限于 for 循环块内部:

    for (let i = 0; i < 5; ++i) { 
     // 循环逻辑
    } 
    console.log(i); // ReferenceError: i 没有定义
    

    3、const 声明

    const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。

    const age = 26; 
    age = 36; // TypeError: 给常量赋值
    
    // const 也不允许重复声明
    const name = 'Matt'; 
    const name = 'Nicholas'; // SyntaxError 
    
    // const 声明的作用域也是块
    const name = 'Matt'; 
    if (true) { 
     const name = 'Nicholas'; 
    } 
    console.log(name); // Matt
    
    

    const 声明的限制只适用于它指向的变量的引用。换句话说,如果 const 变量引用的是一个对象,那么修改这个对象内部的属性并不违反 const 的限制。

    const person = {}; 
    person.name = 'Matt'; // ok
    

    const 在 for 循环中的示例:

    for (const i = 0; i < 10; ++i) {} // TypeError:给常量赋值
    
    // 如果你只想用 const 声明一个不会被修改的 for 循环变量,那也是可以的。
    let i = 0; 
    for (const j = 7; i < 5; ++i) { 
     console.log(j); 
    } 
    // 7, 7, 7, 7, 7
    
    // 这对 for-of 和 for-in 循环特别有意义:
    for (const key in {a: 1, b: 2}) { 
     console.log(key); 
    } 
    // a, b 
    for (const value of [1,2,3,4,5]) { 
     console.log(value); 
    } 
    // 1, 2, 3, 4, 5 
    

    4、声明风格及最佳实践

    ES6 增加 let 和 const 从客观上为这门语言更精确地声明作用域和语义提供了更好的支持。

    1. 不使用 var
      有了 let 和 const,大多数开发者会发现自己不再需要 var 了。限制自己只使用 let 和 const 有助于提升代码质量,因为变量有了明确的作用域、声明位置,以及不变的值。

    2. const 优先,let 次之使用 const 声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。因此,很多开发者认为应该优先使用 const 来声明变量,只在提前知道未来会有修改时,再使用 let。这样可以让开发者更有信心地推断某些变量的值永远不会变,同时也能迅速发现因意外赋值导致的非预期行为

    5、总结

    1. 3 个关键字可以声明变量:var、const 和 let。

    2. 定义变量:操作符+变量名(标识符)

    3. var 声明的特点:

    (1)可以省略关键字自动变为全局变量

    (2)可以重复声明

    (3)可以先访问后声明(声明提升)

    (4)声明范围是函数作用域

    1. let 声明的特点:

    (1)未声明不可使用,会报错

    (2)不可以重复声明

    (3)声明范围是块作用域

    1. const 声明的特点:

    (1)包含 let 所以特点

    (2)声明变量时必须同时初始化变量

    (3)值类型不可修改,引用类型不可修改引用地址

    1. var、let、const 共同点:都可以声明为全局作用域

    相关文章

      网友评论

        本文标题:js变量详解

        本文链接:https://www.haomeiwen.com/subject/jxjqnltx.html