JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行。如果你不能理解javaScript语言的运行机制,或者简单地说,你不能掌握javascript的执行顺序,那你就犹如伯乐驾驭不了千里马,让千里马脱缰而出,四处乱窜。
本文地址:http://blog.csdn.net/chen_zw/article/details/18502937
那么JavaScript是怎么来进行解析的吗?它的执行顺序又是如何的呢?在了解这些之前,我们先来认识几个重要的术语:
1、代码块
JavaScript中的代码块是指由<script>标签分割的代码段。例如:
- <script type="text/javascript">
- alert("这是代码块一");
- </script>
- <script type="text/javascript">
- alert("这是代码块二");
- </script>
JS是按照代码块来进行编译和执行的,代码块间相互独立,但变量和方法共享。什么意思呢? 举个例子,你就明白了:
- <script type="text/javascript">
- alert(str);//因为没有定义str,所以浏览器会出错,下面的不能运行
- alert("我是代码块一");//没有运行到这里
- var test = "我是代码块一变量";
- </script>
- <script type="text/javascript">
- alert("我是代码块二"); //这里有运行到
- alert(test); //弹出"我是代码块一变量"
- </script>
上面的代码中代码块一中运行报错,但不影响代码块二的执行,这就是代码块间的独立性,而代码块二中能调用到代码一中的变量,则是块间共享性。
2、声明式函数与赋值式函数
JS中的函数定义分为两种:声明式函数与赋值式函数。
- <script type="text/javascript">
- function Fn(){ //声明式函数
- }
- var Fn = function{ //赋值式函数
- }
- </script>
声明式函数与赋值式函数的区别在于:在JS的预编译期,声明式函数将会先被提取出来,然后才按顺序执行js代码。
3、预编译期与执行期
事实上,JS的解析过程分为两个阶段:预编译期(预处理)与执行期。
预编译期JS会对本代码块中的所有声明的变量和函数进行处理(类似与C语言的编译),但需要注意的是此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值。
- <script type="text/javascript">
- Fn(); //执行结果:"执行了函数2",同名函数后者会覆盖前者
- function Fn(){ //函数1
- alert("执行了函数1");
- }
- function Fn(){ //函数2
- alert("执行了函数2");
- }
- </script>
- <script type="text/javascript">
- Fn(); //执行结果:"执行了声明式函数",在预编译期声明函数及被处理了,所以即使Fn()调用函数放在声明函数前也能执行。
- function Fn(){ //声明式函数
- alert("执行了声明式函数");
- }
- var Fn = function(){ //赋值式函数
- alert("执行了赋值式函数");
- }
- </script>
- //代码块一
- <script type="text/javascript">
- alert(str);//浏览器报错,但并没有弹出信息窗
- </script>
- //代码块二
- <script type="text/javascript">
- alert(str); //弹窗"undefined"
- var str = "aaa";
- </script>
- //js在预处理期对变量进行了声明处理,但是并没有进行初始化与赋值,所以导致代码块二中的变量是unfiened的,而代码一中的变量是完全不存在<span style="font-family: Arial, Helvetica, sans-serif;">的,所以浏览器报错。</span>
理解了上面的几个术语,相信大家对JS的运行机制已经有了个大概的印象了,现在我们来看个例子:
- <script type="text/javascript">
- Fn(); //浏览器报错:"undefined"
- </script>
- <script type="text/javascript">
- function Fn(){ //函数1
- alert("执行了函数1");
- }
- </script>
为什么运行上面的代码浏览器会报错呢?声明函数不是会在预处理期就会被处理了吗,怎么还会找不到Fn()函数呢?其实这是一个理解误点,我们上面说了JS引擎是按照代码块来顺序执行的,其实完整的说应该是按照代码块来进行预处理和执行的,也就是说预处理的只是执行到的代码块的声明函数和变量,而对于还未加载的代码块,是没法进行预处理的,这也是边编译边处理的核心所在。
现在,让我们来总结整理下:
step 1. 读入第一个代码块。
step 2. 做语法分析,有错则报语法错误(比如括号不匹配等),并跳转到step5。
step 3. 对var变量和function定义做“预编译处理”(永远不会报错的,因为只解析正确的声明)。
step 4. 执行代码段,有错则报错(比如变量未定义)。
step 5. 如果还有下一个代码段,则读入下一个代码段,重复step2。
step6. 结束。
而根据HTML文档流的执行顺序,需要在页面元素渲染前执行的js代码应该放在<body>前面的<script>代码块中,而需要在页面元素加载完后的js放在</body>元素后面,body标签的onload事件是在最后执行的。
- <script type="text/javascript">
- alert("first");
- function Fn(){
- alert("third");
- }
- </script>
- <body onload="Fn()">
- </body>
- <script type="text/javascript">
- alert("second");
- </script>
相关推荐
在单线程模型中,JavaScript的运行机制围绕着任务队列(task queue)展开。所有的任务都会被放入主线程执行,当执行栈(execution context stack)为空时,主线程会读取任务队列,并按先进先出(FIFO)的顺序执行...
关于javascript的运行机制大家都应该有所了解了吧,其实javascript是一个单线程的机制,但是因为队列的关系它的表现会让我们感觉是一个多线程的错觉。下面这篇文章通过实例主要给大家介绍了关于JavaScript中...
JavaScript的执行机制是该语言特性的核心之一,掌握其运行原理对于开发高质量、高性能的Web应用至关重要。下面将从JavaScript单线程的本质、事件循环机制、宏任务与微任务的处理、以及setTimeout和setInterval的工作...
JavaScript中的执行上下文和调用堆栈是理解JS运行机制的关键概念。执行上下文是代码在特定环境中运行的抽象表示,它定义了变量、函数以及`this`关键字的行为。执行上下文主要有三种类型:全局执行上下文(默认的运行...
它的主要特点之一就是支持事件驱动编程和异步编程,然而在其核心运行机制上,JavaScript是单线程的。它通过一个任务队列来管理事件和函数的执行顺序,确保在特定时间只有一个代码块在执行。这种机制虽然在现代浏览器...
在这个例子中,当`test()`函数运行到`await testSometing()`时,`testSometing`立即执行并打印"执行testSometing",然后由于`await`,`test()`函数的执行暂停,控制权交给后续的代码。此时,`promise`开始执行并打印...
JavaScript引擎是JavaScript代码得以运行的基础,它负责解释和执行代码。在深入理解JavaScript引擎工作机制时,我们需要掌握一些关键概念,如执行环境栈、全局对象、执行环境、变量对象、活动对象、作用域和作用域链...
解析后的AST会被转化为可执行代码,这使得JavaScript引擎能够理解和运行代码。 现在,我们来看JavaScript中的声明和赋值。以`var age = 10;`为例,实际上在JavaScript中,这段代码相当于以下两个步骤: 1. **隐式...
总之,JavaScript的运行机制基于单线程、事件驱动和任务队列,理解这些概念对于编写高性能的异步代码至关重要。`setTimeout`的执行是在当前任务完成后,并且只有在所有微任务执行完毕后才会进行,这就解释了为何它在...
在JavaScript中,同步执行意味着代码按照顺序依次运行,等待每一个任务完成后再进行下一个任务。而异步执行则是非阻塞的,它允许代码在等待某个操作(如网络请求)完成的同时,继续执行其他任务。异步执行通常采用回...
1. **同步执行**:代码按照顺序执行,当前的操作必须完成才能执行下一条语句。 2. **异步执行**:当前的操作启动后,不需要等待其完成就可以执行后续代码。当该操作完成后,通过回调函数、事件、Promise等方式通知...
### JavaScript基本知识详解 #### 一、什么是JavaScript JavaScript(简称JS)是一种具有函数优先特性的轻量级、解释型或即时编译型的脚本语言。作为一种弱类型的编程语言,它允许开发者在声明变量时无需指定具体...
在JavaScript中,反射允许我们在运行时检查对象的属性、方法、构造函数等信息,甚至可以动态地调用方法或修改对象的状态。例如,通过`Object.getOwnPropertyDescriptor`和`Object.keys`等内置函数,我们可以获取对象...
### 韩顺平十天JavaScript全套笔记知识点详解 #### JavaScript基本概念与应用领域 - **JavaScript简介**:JavaScript(简称JS)是一种轻量级、解释型或即时编译型的编程语言。它通常用于增强网页的交互性,并且...
在示例中,`fn1`和`fn2`虽然先执行,但`setTimeout`内的回调函数会在延迟后才运行,导致输出顺序不符合预期。即使将`setTimeout`的延迟时间设为0,由于事件循环机制,它依然会在所有同步任务完成后才执行。 2. **...
JavaScript的单线程特性意味着代码按顺序执行,但这并不妨碍它实现异步功能。这是因为浏览器为JavaScript提供了多线程环境。例如,JavaScript引擎(主线程)负责执行代码,而其他辅助线程如定时器线程则处理异步任务...