js变量浅谈

js变量是除了this以外最让人恶心的东西了,还因为烂语法造成各种各样奇奇怪怪的事情发生,下面让我们来谈谈都有什么奇怪的事:

1.用var与不用var

function test(){
    a = 123;
    var b =456;  
}
test();
console.log(a); //123
console.log(b); //报错

容易看出,在函数内部,没有用var定义的变量变成了全局的了,究竟发生了什么事呢?那就是万恶的作用域链在作怪了~~

首先,变量 = 。。。这种赋值写法会先寻找当前作用域有没有这个这个变量,如果没有往父作用域寻找,这样的操作直到window作用域,如果window作用域都没有,就创建一个全局变量,并给其赋值。

在全局环境中,不用var和用var,其实也是有区别的:

a = 123; 
var b =456; 
delete window.a //true
a //ReferenceError: a is not defined [详细了解]
delete window.b //false
b //456

就是说用var定义的全局变量是不能被delete的,不用var定义得到的全局变量都是可以被delete的(包括函数里面不用var定义的)

ps:但是最新版的chrome已经都可以delete了

2.变量提升

//平常直接调用一个没定义的变量
aaa; //报错,aaa is not defined

但是,直接调用后,再定义,就不报错了

aaa; //undefined
var aaa = 123;
aaa;// 123

这就是所谓的变量提升了,js中所有变量和函数都是会先被提到它的作用域的最上方先定义的,就是说上面的代码可以等价成下面的:

var aaa;
aaa; //undefined
aaa = 123;
aaa;// 123

经常面试的时候,会考到相关的问题:

var aaa = 456;
function test(){
    aaa;
    var aaa; = 123;
    aaa;
}
test();

问test中第一个aaa和第二个aaa的值分别是什么?

答案是第一个是undefined,第二个是123,为什么第一个不是456,而是undefined呢,明显就是变量提升的效果了

但是es6的let出现后,这种写发法不允许了,这就是所谓的暂时性死区:

var aaa = 456;
function test(){
    aaa; //Uncaught ReferenceError: aaa is not defined
    let aaa; = 123;
    aaa;
}
test();

 函数的变量提升比var变量的提升优先级更高:

b() // call b second

function b() {
    console.log('call b fist')
}
function b() {
    console.log('call b second')
}
var b = 'Hello world'
原文地址:https://www.cnblogs.com/amiezhang/p/8003769.html