js中声明变量加var和不加var的区别

2020-02-23  本文已影响0人  切磋琢磨_FE

严格模式下,不加var 无法声明变量,会报错 。

我们探讨非严格模式的情况:

先给结论:

1. 不加var声明的全局变量,可以被delete操作符删除。
2. 不加var声明的全局变量,无变量提升。

不加var 无论在什么作用域下,声明的变量都是全局变量。
但是与var 声明的全局变量不同,无var 声明的全局变量可以用delete关键字删除。

考虑如下代码:

    a = '111';
    var b = '222';
    console.log(a)
    console.log('a:', Object.getOwnPropertyDescriptor(window, 'a'));
    console.log('b:', Object.getOwnPropertyDescriptor(window, 'b'));
    delete a;
    delete b;
    console.log(b)
    console.log(a);

运行结果如下:


运行结果

上面代码中 声明的变量a 和变量b 都是全局变量,我们知道全局变量本质是window的属性,所以可以通过Object.getOwnPropertyDescriptor()获取全局变量的属性描述符。显而易见变量a是可删除的,变量b是不可删除的。

关于变量提升

这个很好验证, 考虑如下代码:

console.log(a);  // undefined
console.log(b); //  ReferenceError: b is not defined
b=222;
var a= 111;

结果显而易见,但是 变量b为什么没有声明提升?
这就要涉及到js引擎的编译原理了,js引擎在运行js之前,会对js代码进行预编译,预编译的工作是交个js编译器做的。编译器在遇到 类似 var a = xxx; 这样的语句会执行两个动作:
1.进行LHS查询,不存在a的情况下创建a。
2.生成对a赋值操作的可执行代码(注意,这里只是生成代码,并不执行)。
我猜测,在无var 的情况声明变量 a = xxx; 编译器在执行过程中不会进行第一步操作。

上一篇下一篇

猜你喜欢

热点阅读