学js也挺久了一直没有系统的总结过,现在慢慢地从基础开始把之前遇到的奇怪的问题和坑给总结一下。
var变量提升
变量提升简单来说就是先用后定义,这在java和c这种严格的传统语言来看是完全不行的,但是js允许(严格模式下不允许)
从下面的代码开始
x=7;
console.log(x,y);
var x;
var y=5;
控制台输出的是7和undefined。
解释:
对于x来说,虽然先写的是“x=7”但是在实际parse中,js会先进行变量的创建和初始化,也就是先执行“var x”这一语句。因此x在控制台上输出的是7。
对于y来说,虽然js也将它进行了变量提升,但是var的变量提升只是变量的创建和初始化的提升,并不会提升变量的赋值,所以对于y的操作可以看成是如下代码:
var y;
console.log(y);
y=5;
另外,从if语句块中也可以做到变量提升
console.log(foo);
if(!foo){
var foo=123;
}
console.log(foo);
函数提升
函数提升和变量提升相类似,只不过作用到了函数身上。
示例代码如下:
fuctest();
function fuctest(){
console.log("fuctest-before");
}
function fuctest(){
console.log("fuctest-after");
}
这里的输出是fuctest-after
需要注意有两点:
1.函数提升不仅提升了函数的创建和初始化,还包括有函数的“赋值”,因此不像var变量提升那样会出现undefined。
2.函数提升的时候如果出现同名的情况则取最后赋值的函数。
那么,如果变量和函数同名怎么取呢?
console.log(result1);
function result1(){};
var result1;
console.log(result2);
var result2;
function result2(){};
答案是全部输出函数对象:第一个console输出ƒ result1(){};第二个console输出ƒ result2(){},可以简单理解为函数比变量更能提升。实际上是因为上面提到的函数提升多了一步。
let和const的变量提升
除了var和function之外,es6里面还有两种常用的变量定义关键词:let和const。由于let还会涉及作用域等坑所以讲变量提升时我们先只考虑一个作用域。
let的示例代码如下:
letx=123;
console.log(letx);
let letx;
控制台会报错:初始化之前无法访问(赋值)该变量
可见let的变量提升连初始化这一步也没有提升上来。而是仅仅提升创建该变量这第一步。
const则更加严格,const本意就是为了定义一个无法更改的常量。且不能单纯的只声明,即光写一个“const x”,声明的同时必须赋值(哪怕赋的值是undefined)。而let和var单纯声明的时候会隐式的初始化为undefined。
con=123;
console.log(con);
const con;
console.log(con);
const con;
const con;
console.log(con);
因此上面这三种情况下都会报同一个错:
但是const也是和let一样只有变量创建这一步的提升。
未完待续…