js变量作用域--变量提升
2021-06-24 16:04
标签:color var 对象 enc strong undefined 全局 not 定义 1、JS作用域 在ES5中,js只有两种形式的作用域:全局作用域和函数作用域,在ES6中,新增了一个块级作用域(最近的大括号涵盖的范围),但是仅限于let方式申明的变量。 2、变量声明 3、函数声明 4、变量提升 a情形 b情形 c情形 从上面可以看到,b情形和c情形为什么不同于a情形,就是因为变量提升了(ps: c情形不同于b情形的是判断条件为true,但是这里不是看代码有没有被执行,是看变量有没有被定义)。fn函数里面定义了同名变量tmp,无论在函数的任何位置定义tmp变量,它都将被提升到函数的最顶部。等同于下面情形: 这里需要说明的是,虽然所有的申明(包括ES5的var、function,和ES6的function *、let、const、class)都会被提升,但是var、function、function *和let、const、class的的提升却并不相同!具体原因可以看这里的说明(大体的意思是虽然let,const,class也被提升了,但是却并不会被初始化,这时候去访问他们则会报ReferenceError异常,他们需要到语句执行的时候才会被初始化,而在被初始化之前的状态叫做temporal dead zone)。 因为这样的原因,推荐的做法是在申明变量的时候,将所用的变量都写在作用域(全局作用域或函数作用域)的最顶上,这样代码看起来就会更清晰,更容易看出来那个变量是来自函数作用域的,哪个又是来自作用域链。 5、重复声明 上面的输出其实是:1 2 2。虽然看起来里面x申明了两次,但上面说了,js的var变量只有全局作用域和函数作用域两种,且申明会被提升,因此实际上x只会在最顶上开始的地方申明一次,var x=2的申明会被忽略,仅用于赋值。也就是说上面的代码实际上跟下面是一致的: 6、函数和变量同时提升的问题 上面的输出结果其实是: 这时输出结果就是undefined,知道上面的声明提升的道理就不难理解了。 总结: 要彻底理解JS的作用域和Hoisting,只要记住以下三点即可: 1、所有申明都会被提升到作用域的最顶上 2、同一个变量申明只进行一次,并且因此其他申明都会被忽略 3、函数声明的优先级优于变量申明,且函数声明会连带定义一起被提升 注意: 通过with语句,可以临时改变运行期上下文的作用域链,此时的对非var定义的变量进行访问,会首先访问with中对象的属性,然后才会向上顺着作用域链向上检查该属性。 js变量作用域--变量提升 标签:color var 对象 enc strong undefined 全局 not 定义 原文地址:http://www.cnblogs.com/chendc/p/7158031.html1 var x; //变量声明
2 var x=1; //变量声明并赋值
3 x = 1; // 定义全局变量并赋值
function fn(){}; //函数声明并定义
var fn = function(){}; // 实际上是定义了一个局部变量fn和一个匿名函数,然后把这个匿名函数赋值给了fn
var tmp = new Date();
function fn(){
console.log(tmp); //Wed Jul 12 2017 22:11:56 GMT+0800 (中国标准时间)
}
fn();var tmp = new Date();
function fn(){
console.log(tmp); //undefined
if(false){
var tmp = ‘hello‘;
}
}
fn();
var tmp = new Date();
function fn(){
console.log(tmp); //undefined
if(true){
var tmp = ‘hello‘;
}
}
fn();
var tmp = new Date();
console.log(tmp);
function fn(){
var tmp;
console.log(tmp); //undefined
if(false){
var tmp = ‘hello‘;
}
}
fn();
var x = 1;
console.log(x);
if(true){
var x = 2;
console.log(x);
}
console.log(x);
var x = 1;
console.log(x);
if(true){
x = 2;
console.log(x);
}
console.log(x);
console.log(fn);
function fn(){};
var fn = ‘string‘;
function fn(){}
,也就是函数内容。console.log(fn);
var fn = function fn(){};
var fn = ‘string‘;