JavaScript在页面中的执行顺序(理解声明式函数与赋值式函数) 转载
JavaScript在页面中的执行顺序
https://blog.csdn.net/superhoy/article/details/52946277
JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行。如果你不能理解javaScript语言的运行机制,或者简单地说,你不能掌握javascript的执行顺序,那你就犹如伯乐驾驭不了千里马,让千里马脱缰而出,四处乱窜。
那么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的,而代码一中的变量是完全不存在的,所以浏览器报错。
理解了上面的几个术语,相信大家对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在页面中的执行顺序(理解声明式函数与赋值式函数) 转载的更多相关文章
- 【JavaScript】JavaScript脚本代码的位置及在页面中的执行顺序
三.如何改变Javascript在页面的执行顺序 利用onload <script type="text/javascript">window.onload = f; ...
- javascript的预编译和执行顺序
原文:javascript的预编译和执行顺序 最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题 代码: 代码一<html> ...
- 【分析】浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang)
[分析]浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别(SamWang) 今天无意中看到有关Invoke和BeginInvoke的一些资料,不太清楚它们之间 ...
- Unity脚本在层级面板中的执行顺序测试3
断断续续的写了3篇,以后有时间可以做成一个系列了 前面2篇测试了GameObject的顺序,以及Awake和OnEnable的时机: Unity脚本在层级面板中的执行顺序测试1 http://www. ...
- Unity脚本在层级面板中的执行顺序测试4-附加整理
测试4为一些附加内容,后续的各种tips都加在此. 前几篇测试的链接: Unity脚本在层级面板中的执行顺序测试1 http://www.cnblogs.com/hont/p/4298110.html ...
- Promise对象及它在js中的执行顺序
关于Promise对象的学习及它的执行顺序 学习阮一峰老师的ES6入门后的记录 1.promise的定义 promise是一个对象,通常包裹着一个异步操作,promise对象提供一些接口的方法,返回一 ...
- 八、Spring之深入理解声明式事务
Spring之深入理解声明式事务 何为事务? 事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. 事务的四个属性: 1.原子性(atomicity) 事务是原子性操 ...
- Mac最新Flutter环境搭建运行和对比理解声明式UI
前言 这段时间一直都在学习和写关于SwiftUI的东西,前面也总结了四篇文章来大体上说了下Demo中功能实现的一些细节,后面准备开始了解学习一下Flutter,争取在年前能再用Flutter写一份项目 ...
- 浅谈个人对客户端JavaScript同步、异步、执行顺序等概念的理解
一.同步和异步的概念. 同步:即按代码的顺序执行任务. 在下列代码中,按照同步概念,则是先打印1后打印2. console.log(1); console.log(2); 异步:即执行一个任务的同时执 ...
随机推荐
- Product - 产品经理 - 内容
特别说明 本文是已读书籍的学习笔记和内容摘要,原文内容有少部分改动,并添加一些相关信息,但总体不影响原文表达. - ISBN: 9787568041591 - https://book.douban. ...
- curl指令的坑
今天使用curl指令构造一个docker api访问,一直得不到预期的结果.调试了半天,发现是网址没加引号. token=$(curl -v -XGET -H >& 由于网址跟了一串参数 ...
- Spark GraphX初探
1. Graphx概念 针对某些领域,如社交网络.语言建模等,graph-parallel系统可以高效地执行复杂的图形算法,比一般的data-parallel系统更快. Graphx是将graph-p ...
- vue计算属性VS侦听属性
原文地址 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 Angular ...
- python基础知识(属性property)
属性property property != 类属性和实例属性 访问计算后所得的值 返回所存储的值 创建用于计算的属性 @proper ...
- kali破解wifi密码
开始 1.选择合适的网卡,有些网卡kali识别不了,我用的网卡信息 2.网卡开启监听模式 3.查看监听模式是否开启成功(网卡名称变成wlan0mon说明已经开启成功) 4.输入“airodump-ng ...
- 【转】C# DataTable 导出 Excel 进阶 多行表头、合并单元格、中文文件名乱码
本文原创地址:http://blog.csdn.net/ranbolwb/article/details/8083983 ,转载请保留本行. 本例子是上一篇 DataTable 导出 Excel 的进 ...
- C++学习笔记-异常处理
程序设计的要求之一就是程序的健壮性.希望程序在运行时能够不出或者少出问题.但是,在程序的实际运行时,总会有一些因素会导致程序不能正常运行.异常处理(Exception Handling)就是要提出或者 ...
- day20 logging模块、re模块
今日内容: 1.logging模块 2.re模块 1.logging模块 -- 什么是logging模块 -- logging模块是用来进行记录日志的模块,主要作用是将想要输出的日志进行分级,然后以不 ...
- vultr 更换服务器
今天打算去p站看看电影 结果发现自己的vps被封了......记录一下换服务器的过程 首先去 https://www.17ce.com/ ping一下,发现只有国外的服务器能ping通 果然是被封了. ...