首页 / 更多教程 / js变量作用域--变量提升
js变量作用域--变量提升
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了js变量作用域--变量提升,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1990字,纯文字阅读大概需要3分钟。
内容图文
1、JS作用域
在ES5中,js只有两种形式的作用域:全局作用域和函数作用域,在ES6中,新增了一个块级作用域(最近的大括号涵盖的范围),但是仅限于let方式申明的变量。
2、变量声明
1 var x; //变量声明2var x=1; //变量声明并赋值3 x = 1; // 定义全局变量并赋值
3、函数声明
function fn(){}; //函数声明并定义var fn = function(){}; // 实际上是定义了一个局部变量fn和一个匿名函数,然后把这个匿名函数赋值给了fn
4、变量提升
var tmp = new Date(); function fn(){ console.log(tmp); //Wed Jul 12 2017 22:11:56 GMT+0800 (中国标准时间) }
fn();
a情形
var tmp = new Date(); function fn(){ console.log(tmp); //undefinedif(false){ var tmp = ‘hello‘; } } fn();
b情形
var tmp = new Date(); function fn(){ console.log(tmp); //undefinedif(true){ var tmp = ‘hello‘; } } fn();
c情形
从上面可以看到,b情形和c情形为什么不同于a情形,就是因为变量提升了(ps: c情形不同于b情形的是判断条件为true,但是这里不是看代码有没有被执行,是看变量有没有被定义)。fn函数里面定义了同名变量tmp,无论在函数的任何位置定义tmp变量,它都将被提升到函数的最顶部。等同于下面情形:
var tmp = new Date(); console.log(tmp); function fn(){ var tmp; console.log(tmp); //undefinedif(false){ var tmp = ‘hello‘; } } fn();
这里需要说明的是,虽然所有的申明(包括ES5的var、function,和ES6的function *、let、const、class)都会被提升,但是var、function、function *和let、const、class的的提升却并不相同!具体原因可以看这里的说明(大体的意思是虽然let,const,class也被提升了,但是却并不会被初始化,这时候去访问他们则会报ReferenceError异常,他们需要到语句执行的时候才会被初始化,而在被初始化之前的状态叫做temporal dead zone)。
因为这样的原因,推荐的做法是在申明变量的时候,将所用的变量都写在作用域(全局作用域或函数作用域)的最顶上,这样代码看起来就会更清晰,更容易看出来那个变量是来自函数作用域的,哪个又是来自作用域链。
5、重复声明
var x = 1; console.log(x); if(true){ var x = 2; console.log(x); } console.log(x);
上面的输出其实是:1 2 2。虽然看起来里面x申明了两次,但上面说了,js的var变量只有全局作用域和函数作用域两种,且申明会被提升,因此实际上x只会在最顶上开始的地方申明一次,var x=2的申明会被忽略,仅用于赋值。也就是说上面的代码实际上跟下面是一致的:
var x = 1; console.log(x); if(true){ x = 2; console.log(x); } console.log(x);
6、函数和变量同时提升的问题
console.log(fn); function fn(){}; var fn = ‘string‘;
上面的输出结果其实是: function fn(){}
,也就是函数内容。
console.log(fn); var fn = function fn(){}; var fn = ‘string‘;
这时输出结果就是undefined,知道上面的声明提升的道理就不难理解了。
总结:
要彻底理解JS的作用域和Hoisting,只要记住以下三点即可:
1、所有申明都会被提升到作用域的最顶上
2、同一个变量申明只进行一次,并且因此其他申明都会被忽略
3、函数声明的优先级优于变量申明,且函数声明会连带定义一起被提升
注意:
通过with语句,可以临时改变运行期上下文的作用域链,此时的对非var定义的变量进行访问,会首先访问with中对象的属性,然后才会向上顺着作用域链向上检查该属性。
原文:http://www.cnblogs.com/chendc/p/7158031.html
内容总结
以上是互联网集市为您收集整理的js变量作用域--变量提升全部内容,希望文章能够帮你解决js变量作用域--变量提升所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。