js 程序执行与顺序实现详解
JavaScript是一种描述型脚本语言,由浏览器进行动态的解析与执行,浏览器对于不同的方式有不同的解析顺序,详细介绍如下,感兴趣的朋友可以参考下哈
函数的声明和调用
JavaScript是一种描述型脚本语言,由浏览器进行动态的解析与执行。函数的定义方式大体有以下两种,浏览器对于不同的方式有不同的解析顺序。
代码如下:
//“定义式”函数定义
function Fn1(){
alert("Hello World!");
}
//“赋值式”函数定义
var Fn2 = function(){
alert("Hello wild!");
}
页面加载过程中,浏览器会对页面上或载入的每个js代码块(或文件)进行扫描,如果遇到定义式函数,则进行预处理(类似于C等的编译),处理完成之后再开始由上至下执行;遇到赋值式函数,则只是将函数赋给一个变量,不进行预处理(类似1中变量必须先定义后引用的原则),待调用到的时候才进行处理。下面举个简单的例子:
代码如下:
//“定义式”函数定义
Fn1();
function Fn1(){
alert("Hello World!");
}
正常执行,弹出“Hello World!”,浏览器对Fn1进行了预处理,再从Fn1();开始执行。
代码如下:
//“赋值式”函数定义
Fn2();
var Fn2 = function(){
alert("Hello wild!");
}
Firebug报错:Fn2 is not a function,浏览器未对Fn2进行预处理,依序执行,所以报错Fn2未定义。
3. 代码块及js文件的处理
“代码块”是指一对<script type=”text/网页特效”></script>标签包裹着的js代码,文件就是指文件啦,废话:D
浏览器对每个块或文件进行独立的扫描,然后对全局的代码进行顺序执行(2中讲到了)。所以,在一个块(文件)中,函数可以在调用之后进行“定义式”定义;但在两个块中,定义函数所在的块必须在函数被调用的块之前。
很绕口,看例子好了:
代码如下:
<script type="text/javascript">
Fn();
</script>
<script type="text/javascript">
function Fn(){
alert("Hello World!");
}
</script>
// 报错:Fn is notdefined,两个块换过来就对了
4. 重复定义函数会覆盖前面的定义
这和变量的重复定义是一样的,代码:
代码如下:
function fn(){
alert(1);
}
function fn(){
alert(2);
}
fn();
// 弹出:“2”
如果是这样呢:
代码如下:
fn();
function fn(){
alert(1);
}
function fn(){
alert(2);
}
// 还是弹出:“2”
还是弹出“2”,为什么?2都讲了好吧…
5. body的onload函数与body内部函数的执行
body内部的函数会先于onload的函数执行,测试代码:
代码如下:
//html head...
<script type="text/javascript">
function fnOnLoad(){
alert("I am outside the Wall!");
}
</script>
<body onload="fnOnLoad();">
<script type="text/javascript">
alert("I am inside the Wall..");
</script>
</body>
//先弹出“I am inside the Wall..”;
//后弹出“I am outside the Wall!”
body的onload事件触发条件是body内容加载完成,而body中的js代码会在这一事件触发之前运行(为什么呢?6告诉你..)
6. JavaScript是多线程or单线程?
严格来说,JavaScript是没有多线程概念的,所有的程序都是“单线程”依次执行的。
举个不太恰当的例子:
代码如下:
function fn1(){
var sum = 0;
for(var ind=0; ind<1000; ind++) {
sum += ind;
}
alert("答案是"+sum);
}
function fn2(){
alert("早知道了,我就是不说");
}
fn1();
fn2();
//先弹出:“答案是499500”,
//后弹出:“早知道了,我就是不说”
那你肯定要问:那延时执行、Ajax异步加载,不是多线程的吗?没错,下面这样的程序确实看起来像“多线程”:
代码如下:
function fn1(){
setTimeout(function(){
alert("我先调用")
},1000);
}
function fn2(){
alert("我后调用");
}
fn1();
fn2();
// 先弹出:“我后调用”,
// 1秒后弹出:“我先调用”
看上去,fn2()和延时程序是分两个过程再走,但其实,这是JavaScript中的“回调”机制在起作用,类似于操作系统中的“中断和响应” —— 延时程序设置一个“中断”,然后执行fn2(),待1000毫秒时间到后,再回调执行fn1()。
同样,5中body的onload事件调用的函数,也是利用了回调机制——body加载完成之后,回调执行fnOnLoad()函数。
Ajax请求中的数据处理函数也是一样的道理。
关于JavaScript线程问题的更深入讨论,看这篇 javascript中的线程之我见,以及infoQ上的 JavaScript多线程编程简介。
困了,再说一下回调函数吧。
7. 回调函数
回调函数是干嘛用的?就是回调执行的函数嘛,又废话:D
如6所说,最常见的回调就是onclick、onmouseover、onmousedown、onload等等浏览器事件的调用函数;还有Ajax异步请求数据的处理函数;setTimeOut延时执行、setInterval循环执行的函数等。
干脆我们写一个纯粹的回调函数玩:
代码如下:
function onBack(num){
alert("姗姗我来迟了");
// 执行num个耳光
}
function dating(hours, callBack){
var SP= 0; // SP,愤怒值
//女猪脚在雪里站了hours个钟头
//循环开始..
SP ++;
//循环结束...
callBack(SP);
}
dating(1, onBack);
js 程序执行与顺序实现详解的更多相关文章
- [转载]js 程序执行与顺序实现详解
http://www.jb51.net/article/36755.htm JavaScript是一种描述型脚本语言,由浏览器进行动态的解析与执行,浏览器对于不同的方式有不同的解析顺序,详细介绍如下, ...
- JS中的函数节流throttle详解和优化
JS中的函数节流throttle详解和优化在前端开发中,有时会为页面绑定resize事件,或者为一个页面元素绑定拖拽事件(mousemove),这种事件有一个特点,在一个正常的操作中,有可能在一个短的 ...
- Myeclipse程序调试快捷键及步骤详解
Myeclipse程序调试快捷键及步骤详解: 调试快捷键 Eclipse中有如下一些和运行调试相关的快捷键. 1. [Ctrl+Shift+B]:在当前行设置断点或取消设置的断点. ...
- 使用events.EventEmitter 控制Node.js 程序执行流程
使用events.EventEmitter 控制Node.js 程序执行流程 标题写的可能也不太对,大家领会精神: Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. ...
- Node.js中环境变量process.env详解
Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...
- js replace 与replaceall实例用法详解
这篇文章介绍了js replace 与replaceall实例用法详解,有需要的朋友可以参考一下stringObj.replace(rgExp, replaceText) 参数 stringObj 必 ...
- java程序运行时内存分配详解
java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下 一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...
- 【转】RocketMQ事务消费和顺序消费详解
RocketMQ事务消费和顺序消费详解 转载说明:该文章纯转载,若有侵权或给原作者造成不便望告知,仅供学习参考. 一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消 ...
- JS JSOP跨域请求实例详解
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题.这篇文章主要介绍了JS JSOP跨域请求实例详解的相关资料,需要的朋友可以参考下 ...
随机推荐
- 【串线篇】spring boot全面接管springMvc
一.Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoC ...
- 了解卷积神经网络如何使用TDA学习
在我之前的文章中,我讨论了如何对卷积神经网络(CNN)学习的权重进行拓扑数据分析,以便深入了解正在学习的内容以及如何学习它. 这项工作的重要性可归纳如下: 它使我们能够了解神经网络如何执行分类任务. ...
- handy源码阅读(三):SafeQueue类
SafeQueue类继承与信号量mutex(用于加锁),nonocopyable 定义如下: template <typename T> struct SafeQueue : privat ...
- python+selenium+pytest+html报告
背景:python+selenium+pytest+html报告 环境:我的是本机的Jenkins配置本机的代码 前提:要下载好HTML Publisher plugin插件[系统管理>管理插件 ...
- Xcode模拟器快捷键
command + 左右 = 横竖屏旋转 command + H + H = 切入层级后台模式
- Centos7防火墙和SELinux的开启和关闭
在虚拟机里面开启多个服务,对应多个端口,在防火墙开启的情况下,就要对外开放端口,这样客户端才能正常访问,但比较繁琐,关闭更直接点. 防火墙 临时关闭防火墙 systemctl stop firewal ...
- 透明的LISTVIEW
.NET就是封装的太密了,有时很多时候让我们反而更麻烦,特别是COPY不到的时候,又不懂自已想的话,说土一点就是死路一条, 记得以前经常用一句话,C++支持,可C#他不支持啊!就这样安慰自已 其实做多 ...
- vue项目中使用element的dialog中引入ztree却不能初始化解决办法
一开始我在 里边写的,发现获取不到,那么采用dialog自带的回调函数,窗口打开后opend进行处理, 结果:
- 170821-关于SpringMVC的知识点
1.SpringMVC 概述以及优势 SpringMVC和Spring的关系: 软件开发的三层架构: web层[表示层.表现层]---->Service层---->Dao[DataBas ...
- 写一个简单易用可扩展vue表单验证插件(vue-validate-easy)
写一个vue表单验证插件(vue-validate-easy) 需求 目标:简单易用可扩展 如何简单 开发者要做的 写了一个表单,指定一个name,指定其验证规则. 调用提交表单方法,可以获取验证成功 ...