变量提升
JavaScript的变量提升有两种,用var声明的变量以及用function声明的变量。
用var声明的变量
我们先来看下面这段代码,a的值是多少
代码1
console.log(a); var a;
按照以往编程语言的思路来看,代码自上而下运行,按这种思路,会报错,因为执行到第2行时,变量a还没有定义,所以会报错a is not defined
然而事实上答案是undefined
好,抱着疑惑,我们看下面的代码
var a; console.log(a);
我们发现,这两段代码是一样的,那么又有一个新的问题,是不是有没有var a都无所谓,它的答案始终是undefined,才造成了以为变量会提升的错觉,于是我写了代码3
代码3
console.log(a);
好,它终于报错了,所以这证明了javaScript代码并不是自上而下执行的,至少从表面看上面是这样的。
于是我们再看代码4
代码4
console.log(a); var a = 2;
因为变量提升嘛,所以答案是2,然而事实上,它依然是undefined,why?
这时候我们有请编译器这位负责语法分析及代码生成等脏活累活的大佬。
编译器在看到var a = 2;,它会将其看做两个声明,var a;和a = 2,第一个声明在编译阶段进行,第二个声明会被原地等待执行阶段。
也就是说上面代码,会变成下面的这段代码
var a; console.log(a); a = 2;
所以最终会是undefined
好,我在啰嗦一下,看这段代码5
代码5
a = 2; var a; console.log(a);
我想大家应该已经知道这段代码执行时的真正顺序及其答案了,没错,答案是2,但我想说的是把第2行给注释掉,答案依然是2,但这个和变量提升没啥关系了,是严格模式与非严格模式的锅,在非严格模式下允许开发者可以不使用声明变量的关键字,但在严格模式下是不可以的,它会报错的。
用function声明的变量
与var一样,function声明的变量依然会提升。
log(5); function log(mes){ console.log(mes) }
按照之前的变量提升的理解,这段代码的真正顺序是这样的,
function log(mes){ console.log(mes) } log(5);
很好,很正确,那么再看下一段代码
log(5); var log = function(mes){ console.log(mes) }
它报错了,log is not a function,从这里我们可以看出,这种函数表达式是不会被提升的,只有函数声明才会被提升,试着在最前面新增一行代码console.log(log),会先输出undefined。
所以这里的真正顺序是
var log; log(); //这时候只是声明了log这个变量,并不是函数,却用函数的方法调用它,所以会报错,说这不是一个函数。 log = function(mes){ console.log(mes) }
在function里用var声明变量
我们虽然知道,var声明的变量会提升,但并不知道会提升到哪个程度。
在此之前来看一段代码
var a = 4; function foo(){ var a = 5; console.log(a); } foo(); console.log(a)
答案是5,4,先输出5,再输出4。
用var声明的变量是有函数作用域的,所以foo里的a和foo外面的a没有任何关系,这种情况正是我想要的。
再改下代码
function foo(){ a = 5 console.log(a); var a; } foo(); console.log(a)
答案是5,a is not defined
第4行代码输出5,第9行报错。
这种情况就是变量提升只会提升到变量所在的 作用域的顶部,不会提升到父级作用域。
因此可以得出一个结论:变量提升只会将变量提升到自己所在的作用域的顶部
函数优先
既然用var和function的变量都有提升的功能,那如果同一个变量用这两种都声明会怎样,好吧,看标题就知道了,函数优先。
具体看下代码
foo(); var foo; function foo(){ console.log(1) } foo = function(){ console.log(2) }
答案是1
这段代码其实这样子的
function foo(){ console.log(1) } foo();// 1 foo = function(){ console.log(2) }
仔细一看,var foo;没了,没错,它被引擎忽略了,认为重复声明所以把它抛弃了。
好,既然var声明的变量比不了函数声明,那就用函数声明,多次声明同个变量。
foo() function foo(){ console.log(1); } foo() function foo(){ console.log(2); } foo() function foo(){ console.log(3); } foo()
foo声明了三次,调用了四次,每次调用的结果都是3,所以最后的函数声明会覆盖之前的函数声明
但是var还想挣扎一下,觉得还是有必要证明自己的存在感的。
foo() function foo(){ console.log(1); } var foo; foo() foo = function(){ console.log(2); } foo() function foo(){ console.log(3); } foo()
仔细看,中间那部分代码改了,依次输出3,3,2,2
虽然var foo被忽略了,但下面的函数还是有用的,这段代码可以看成是这样的
function foo(){ console.log(3); } foo();//3 foo();//3 foo = function(){ console.log(2); } foo();//2 foo();//2
在普通块内部声明函数
之前是在作用域声明函数,现在来块里面声明函数
function foo(){ console.log(b); // undefined b(); //TypeError: b is not a function var a = true; if(a){ function b(){ console.log(2) } //下面这段代码和上面的结果一样 // var b = function(){ // console.log(2) // } } //b() --> 这里会被执行 } foo()
从上面看上去,b是undefined,证明这个变量还是有的,只不过它并不是一个函数,这情况和用函数表达式差不多。
总结
1、提升分为函数声明提升和变量声明提升
2、声明变量用var,声明函数用function
3、变量提升会将变量提升到自己所在作用域的顶部
4、函数表达式不存在提升的机制
5、函数声明和变量声明同时声明同一个标识符时,函数声明优先
6、多个函数声明同一个标识符时,最后一个声明覆盖先前的声明
推荐教程:js教程
以上是详细介绍js中的变量提升机制的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

Dreamweaver Mac版
视觉化网页开发工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

Atom编辑器mac版下载
最流行的的开源编辑器

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。