JS中带var和不带var的区别

2020-12-20  本文已影响0人  _hider

以下案例是给变量a和变量b赋值,只是变量bvar,而变量a没有,分析下两者的区别:

//声明变量 a 不带 var
console.log(a); // Uncaught ReferenceError: a is not defined
console.log(window.a); // undefined
console.log("a" in window); // false
a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log("a" in window); // true 

//声明变量`b`带`var`:
console.log(b); // undefined
console.log("b" in window); // true
console.log(window.b); // undefined
var b = 2;
console.log(b); // 2
console.log(window.b); // 2
console.log("b" in window); // true
只有带var的变量才会变量提升

在变量提升阶段,变量b提升,默认为undefined,所以代码开始输出变量b
的时候是undefined,因为变量a没有用var,直接赋值为1,所以不会变量提升导致输出变量a的时候直接报错。

不加var的本质是window的属性

当执行a = 1时,浏览器在解析时会认为这是简化写法,会在a前加window,相当于给window.a = 1。所以在a = 1之前输出"a" in window是不存在的,当执行了a = 1就有值了。
那为何在var a = 1之前输出"a" in window是存在的呢?因为存在映射机制。

全局变量和window中的属性存在映射机制

映射机制就是全局作用域下声明一个变量,也相当于给window全局对象上设置了一个同样属性,私有作用域中声明的私有变量和window没有关系。
在变量提升阶段,变量b提升,默认为undefined,相当于在window对象上添加了一个属性b,属性值为undefined。在变量b赋值成12的时候,再输出window.b的时候也变成了12

以上是在全局作用域中,如果在函数作用域中声明一个变量带不带var又是否有区别?

function fn() {
    var a = 1;
    b = 2;
    console.log(a);
    console.log(b);
}
fn();
console.log("b" in window); // true
console.log(window.b); // 2

在函数作用域有ab两个变量,a变量声明带var,它是私有变量,只对当前作用域有效,和全局作用域没关系。要注意的是私有变量是私有作用域中声明的,它不会和window存在映射机制。

之前案例中验证了在全局作用域中不加var的本质是window的属性,那在函数作用域中是否也一样?通过代码可以发现执行完fn后,在全局输出window.b会得到同样的结果,所以不带var不是私有变量,会向他上级作用域查找,在作用域lian7查找的过程中,如果找到window也没有这个变量的话,就会给window设置一个属性。

var a=1 , b=2 和 var a=b=1有什么区别?

JS中经常发现有下面的写法,又分别表示什么意思呢?

var a = 1,
    b = 2;
// 等价于
var a = 1;
var b = 2;
 9
var a = b = 1;
// 等价于
var a = 1;
b = 1;
上一篇下一篇

猜你喜欢

热点阅读