JavaScript之语言基础

125 阅读2分钟

定义变量

  • var

    • 声明作用域

      • 会成为包含它的函数的局部变量
      function test () {
        var name = '小明'
      }
      test()
      console.log(name) // name在函数执行之后被销毁
      
      • 定义全局变量
      function test () {
        name = '小明'
      }
      test()
      console.log(name) // 调用及赋值,在外面可以访问到
      
      • 注意的点
        1. 虽然可以通过省略var操作符定义全局变量,但不推荐这么做。
        2. 在局部作用域中定义的全局变量很难维护,也会造成困惑。
        3. 这是因为不能一下子断定省略var是不是有意而为之。
        4. 在严格模式下,如果像这样给未声明的变量赋值,则会导致抛出ReferenceError。
    • var声明提升

      • 把变量声明提升到函数作用域的顶部
      function foo(params) {
        console.log(age) // undefined
        var age = 18
      }
      foo()
      等同于
      function foo(params) {
        var age
        console.log(age)
        var age = 18
      }
      foo()
      
      • 可以反复使用var声明同一个变量
  • let

    • 声明范围是块作用域
     if (true) {
       // 块作用域
       let age = 18
       console.log(age) // 18
      }
      console.log(age) // age is not defined
    
    • 不允许同一个块作用域中出现冗余声明
      let age
      let age  // Identifier 'age' has already been declared
      
    • 暂时性死区
      • 在解析代码时,JavaScript引擎也会注意出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量。在let声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出ReferenceError。
      console.log(age) //
      let age = 18
      
    • 全局声明
        var name = '小明'
        console.log(window.name) // 小明
      
        let age = 18
        console.log(window.age); // undefined
      
    • for循环中的let声明
        // let出现之前,for循环定义的迭代变量会渗透到循环体外部
        for (var index = 0; index < 5; index++) {
          setTimeout(() => console.log(index), index * 1000)
        }
        // 打印5次
        // 解决方案
        for (var index = 0; index < 5; index++) {
          setTimeout(i => console.log(i), index * 1000, index)
        }
        for (var index = 0; index < 5; index++) {
          (i => setTimeout(_ => console.log(i), i * 1000))(index)
        }
        for (let index = 0; index < 5; index++) {
          setTimeout(_ => console.log(index), index * 1000)
        }
      
  • const

    • 声明与let基本相似,唯一的区别是声明变量时必须同时初始化变量,修改常量的时候会报错
    • const 声明变量引用的是一个对象,可以修改这个对象的内部属性
    • for-of 和for-in 循环对象,推荐使用

声明风格及最佳实践

  • 不使用var

    • 明确了作用域
    • 声明位置
    • 常量,不变的值
    • 重复声明
    • 有助于提升代码质量
  • const优先,let次之

    • 浏览器运行时强制保持变量不变
    • 让静态代码分析工具提前发现不合法的赋值操作
    • 提前预知会有修改的时候用let