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'