恶心的 var

220 阅读2分钟
  1. 上古 var 变量和声明函数的名字相同同会有问题
  2. 上古模式和现代模式的 var 也不同
  3. ==现代模式就是 “use strict”==, 也就是严格模式, 现代模式下也能使用上古的声明变量的 var, 但其行为与 “use strict” 之前==可能==不一致, 这种不可预测或者说行为的难以分析绝对是设计缺陷
  4. let 和 const 是现代的声明变量的方式, 但上古环境也能使用这两个关键字, 好在 let 和 const 即使在上古模式行为也很现代 (所以现代 = 规则制定者脑子清醒, 上古 = 规则制定者没想明白)
  • 上古 js 没有块级作用域, 但变量与函数同名会导致怪异的现象, 用了 “use strict” 后直观许多

    var a = 10;
    {
    a = 99;
    function a() { }
    a = 30;
    }
    console.log(a); // 99
    
    "use strict";
    var a = 10;
    {
    a = 99;
    function a() { }
    a = 30;
    }
    console.log(a); // 10
    
    /* 只在 nodejs 环境里是 10, 在 edge 和 chrome 浏览器无论有没有 "use strict" 都输出 99 */
    
  • 上古没块级, 却不说明花括号没影响, 比如这个和上面的就不一样

    var a = 10;
    a = 99;
    function a() {}
    a = 30;
    console.log(a); // 30
    
    // 上古和现代都是 30
    
  • var 出来的变量在同名函数出来之前就赋值优先级比较高, 反之函数的优先级高 (骂出声)

    function a(){}
    var a;
    console.log(a); // [Function: a]
    var b;
    function b(){}
    console.log(b) // [Function: b]
    var c=1;
    function c(){}
    console.log(c); // 1
    function d(){}
    var d=1;
    console.log(d); // 1
    

还有更恶心的

  • 函数里 console 一下

    var a = 10;
    {
    function a() {console.log(a)} // [Function: a]
    }
    console.log(a()) // undefined
    console.log(a); // [Function: a]
    
  • 这特么居然也报错

    var a = 10;
    {
    a = 99;
    function a() {console.log(a)} // TypeError: a is not a function
    }
    console.log(a())
    

    没花括号也不行

    var a = 10;
    a = 99;
    function a() {console.log(a)} // TypeError: a is not a function
    console.log(a())
    

如果是现代模式, 就会叫你别重复声明变量

let a = 10;
a = 99;
function a() {} // SyntaxError: Identifier 'a' has already been declared
console.log(a())
/* 无论是否用 "use strict", 都会抛这个错, 美滋滋 */