1.在console中直接打印a
console.log(a);
其结果是直接报错:a is not defined
2.观察以下两段代码的执行结果
第一段
console.log(b);//undefined
var b = 1;
console.log(b);//1
第二段
var c;
console.log(c);//undefined
c=1;
console.log(c);//1
所以,上边的代码效果是一样的。
可以看出,在第一段代码中,第一行之前尽管没有定义b,但是并没有报not defined,而是像第二段代码一样,好像是把b提前声明了,但是没有赋值。
这就是变量提升。
在ES6之前,js没有块级作用域的概念,只有全局作用域和函数作用域。变量提升,意味着将变量的声明提升至变量作用域最开始的部分。
函数存在同样的问题,但是现象却不完全相同。观察以下代码:
console.log(f1);
function f1(){
}
其结果是f f1(){},就像是把函数放在了console.log之前声明一样。
至于为什么没有打印出undefined,我觉得函数的声明和变量的声明是一样的,但是变量是需要赋值的,所以没有赋值的变量是undefined,但是函数已经声明过了,就不存在undefined的问题了。
不过下边的代码,依然是变量声明的问题,与函数没有关系
console.log(d);//undefined
var d = function(){};
console.log(d);//f(){}
console.log(a);
其结果是直接报错:a is not defined
2.观察以下两段代码的执行结果
第一段
console.log(b);//undefined
var b = 1;
console.log(b);//1
第二段
var c;
console.log(c);//undefined
c=1;
console.log(c);//1
所以,上边的代码效果是一样的。
可以看出,在第一段代码中,第一行之前尽管没有定义b,但是并没有报not defined,而是像第二段代码一样,好像是把b提前声明了,但是没有赋值。
这就是变量提升。
在ES6之前,js没有块级作用域的概念,只有全局作用域和函数作用域。变量提升,意味着将变量的声明提升至变量作用域最开始的部分。
函数存在同样的问题,但是现象却不完全相同。观察以下代码:
console.log(f1);
function f1(){
}
其结果是f f1(){},就像是把函数放在了console.log之前声明一样。
至于为什么没有打印出undefined,我觉得函数的声明和变量的声明是一样的,但是变量是需要赋值的,所以没有赋值的变量是undefined,但是函数已经声明过了,就不存在undefined的问题了。
不过下边的代码,依然是变量声明的问题,与函数没有关系
console.log(d);//undefined
var d = function(){};
console.log(d);//f(){}
因为var d=function(){}其本质依然是变量声明。
3.考虑以下代码
A.
var sayHello = function() {
return 'Hello var';
};
function sayHello(name) {
return 'Hello function';
};
sayHello();
B.
function sayHello(name) {
return 'Hello function';
};
var sayHello = function() {
return 'Hello var';
};
sayHello();
A和B的运行结果都是Hello var。这说明事实上,虽然都有提升,但function的提升更靠前,即顺序为function sayHello(){}->var sysHello;->sysHello=function(){}
4.变量的作用域
var c=0;console.log(d);if(false){var d=1;}
以上代码可以看出d为undefined的,并不是not defined。由此可以看出ES5的变量作用域只是全局和函数作用域了,并不存在ES6所谓的块级作用域。