原文:JS的预编译和执行顺序 详析
最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题
代码:
复制代码
代码一
<head>
<title>事件处理</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<script type='text/javascript'>
//页面在在完成加载后
window.onload=function(){
var input=document.getElementById('button');
var p=document.getElementById('p');
var i=1;
while(input){
input.onclick=function(){
p.innerHTML+='<br />('+ i +') '+this.nodeName;
}
i++;
input=input.parentNode;
}
}
</script>
</head>
<body>
<div>
<input type='button' value='Event事件' id='button' />
<p id='p'>事件捕获的顺序:</p>
</div>
</body>
</html>
复制代码
显示的结果为:
当我更改了代码中红色的部分后得到的结果又不相同:
复制代码
代码二
<html>
<head>
<title>事件处理</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<script type='text/javascript'>
//页面在在完成加载后
window.onload=function(){
var input=document.getElementById('button');
var p=document.getElementById('p');
var i=1;
while(input){
input.onclick=function(){
p.innerHTML+='<br />('+ i++ +') '+this.nodeName;
}
input=input.parentNode;
}
}
</script>
</head>
<body>
<div>
<input type='button' value='Event事件' id='button' />
<p id='p'>事件捕获的顺序:</p>
</div>
</body>
</html>
复制代码
得到的结果为:
得出这两种不同的结果那是因为javascript代码在运行时有预编译和执行两个阶段,在预编译阶段会对函数和变量进行处理,对所有的声明变量会赋值为underfined,对所有的声明函数也会赋值为函数的定义。
下面我们来测试javascript的执行过程
1.javascript代码执行顺序时按照脚本标签<script>出现的顺序来确定的,浏览下面页面你会发现代码是按从上到下的顺序执行的
复制代码
<script type='text/javascript'>
alert('one');
</script>
<script type='text/javascript'>
alert('two');
</script>
<script type='text/javascript'>
alert('three');
</script>
复制代码
2. 因为变量在预编译时被赋予一个undefined初值,所以下面代码中,第一个变量name在代码中没有被赋值,所有就延用undefined这个值,下面的name被赋予了Jude,所以第二次输出的是Jude这个字符。
<script type='text/javascript'>
alert(name); //显示undefined
var name='Jude';
alert(name); //显示Jude
</script>
3.从如下结果中我们知道先是连续两次输出Hello Wrold!,最后连续两次输出test,得出这样的结果是因为javascript并非是完全按照顺序执行的,而是在执行之前先进行一个预编译,预编译 时声明式函数被提取出来,优先执行,而且相同的函数会进行覆盖,再执行赋值式函数。
复制代码
<script type='text/javascript'>
test(); //输出Hello World!
function test(){
alert('hello'); //声明式函数
}
test(); //输出Hello World!
var test=function(){ //赋值式函数
alert('test');
}
test(); //输出test
function test(){ //声明式函数
alert('Hello World!');
}
test(); //输出test
</script>
复制代码
4.下面代码显示显示hello,再显示hello world!,这是因为javascript中的给个代码块是相互独立的,当脚本遇到第一个<script>标签时,则javascript 解析器会等这个代码块加载完成后,先对它进行预编译,然后再执行之,然后javascript解析器准备解析下一个代码块,由于javascript是按 块执行的,所有一个javascript调用下一个块的函数或者变量时,会出现错误
复制代码
<script type='text/javascript'>
function test(){
alert('hello'); //显示hello
}
test()
</script>
<script type='text/javascript'>
function test(){
alert('hello world!'); //显示hello world!
}
test()
</script>
复制代码
5.虽然javascript是按块执行的,但不同的块却属于相同的全局作用域,不同的块的变量和函数式可以相互使用的,也就是某个块可以使用前面块的变量和函数,却不可以使用它之后的块的变量和函数
复制代码
<script type='text/javascript'>
alert(name); //显示undefined
var name='Jude';
function test(){
alert('hello');
}
fun(); //不能调用下一个块的函数
</script>
<script type='text/javascript'>
alert(name); //可以调用上一个块的变量,显示Jude
test(); //可以调用上一个块的函数,显示hello
function fun(){
alert('fun');
}
</script>
复制代码
6.javascript在预编译阶段是以函数来划分作用域的,然后再通过var 声明的变量来与声明函数开辟内存空间,对var变量赋初值undefined。在执行阶段再根据作用域来嘴变量进行赋值.
第一个代码块中函数里面的变量a是局部变量,因为a在函数内重新用var定义,所以输出undefined,而变量b是全局变量,因为在函数内没有用var重新声明b,所以在给变量b赋值时到全局变量中找全局变量b的值,所以输出的是b.
第二个代码块中的函数内都重新声明了变量a和b,所以他们都是函数内的局部变量,所以都输出undefined。
复制代码
<script type='text/javascript'>
var a='a';
var b='b';
function test(){
alert(a); //显示undefined
alert(b); //显示b
var a='test';
}
test();
</script>
<script type='text/javascript'>
var a='a';
var b='b';
function test(){
alert(a); //显示undefined
alert(b); //显示undefined
var a='test';
var b='test';
}
test();
</script>
复制代码
综上所述,javascript在执行时的步骤是:
1、先读入第一段代码块
2、对代码块进行语法分析,如果出现语法错误,直接执行第5步骤
3、对var变量和function定义的函数进行“预编译处理”(赋值式函数是不会进行预编译处理的)
4、执行代码块,有错则报错
5、如果还有下一段代码块,则读入下一段代码块,重复步骤2
6、结束
- JS的预编译和执行顺序 详析(及全局与局部变量)
最近在复习javascript的事件处理时发现了一个问题,于是总结一下:javascript的预编译和执行顺序的问题: <html> <head> <title> ...
- JS 的预编译和执行顺序
脚本执行js引擎做的工作: 语法分析 预编译 解释执行
- JS之预编译和执行顺序(全局和函数)
预编译的两种情况 全局: 1.全局 直接是script标签中的代码,不包括函数执行 执行前: 1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析 2.分析变量声明 ...
- 关于JavaScript预编译和执行顺序以及函数引用类型的思考
昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了.问题抽象出来是这样的: <script > ...
- javascript的预编译和执行顺序
原文:javascript的预编译和执行顺序 最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题 代码: 代码一<html> ...
- javascript运行机制之执行顺序详解(转)
转自http://www.admin10000.com/document/3385.html JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言, ...
- javascript 执行顺序详解
JavaScript是一种描述 型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解javaScript 语言的运行机制,或者简 ...
- javascript运行机制之执行顺序详解
1.代码块 指的的是有标签分割的代码段. 例如: <script type="text/javascript"> alert("这是代码块一"); ...
- JavaScript 运行机制之执行顺序详解
JavaScript是一种描述型脚本语言,它不同于 Java 或 C# 等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解 JavaScript 语言的运行机制 ...
随机推荐
- pkg_zhgl
CREATE OR REPLACE PACKAGE BODY PKG_ZHGL AS --账户管理包 code szn 20110829 --账户管理服务包 --定义本包中需要引用到的常量 --定义说 ...
- Hibernate 笔记1
Hibernate表generator标签的作用,如下图,
- .NET C#操作文件系统数据的常用方法总结 part1
目录导航 1.0开启文件隐藏属性 1.1开启文件夹只读属性 1.2输出子文件夹路径 1.3统计文件数目 1.4批量重命名文件 1.5分割文件 1.6拼接文件 1.7读取用逗号分割的值 1.8读写压缩数 ...
- django学习之Model(三)QuerySet
接下来主要学习Models中的Making queries 写好models.py后,django会自动提供一个数据库的抽象API,来实现CRUD(create, retrieve, update, ...
- ajax请求响应中用window.open打开新窗口会被浏览器拦截的解决方式
一.问题描述 ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是会被浏览器给拦截了,需要用户点下. 二.问题分析 浏览器之所以拦截新开窗口是因为该操作并 ...
- JSON数组分配输出每个li
有这么一个JSON数组,需求是只需要输出每个数组里面的某个值,不需要全部输出来. var data = [ { ", "Cost":"13,642.41&quo ...
- Unity3d 网络编程(二)(Unity3d内建网络各项參数介绍)
这里是全部Unity3d在网络中能用到相关的类及方法.纵观參数功能, Unity3d来写一个手游是不二的选择: RPC 能够传递的參数 int float string NetworkPlayer N ...
- java--实例成员 & 静态成员
class run{ static String str1 = "静态变量"; String str2 = "非静态变量"; public static voi ...
- docker学习笔记4:利用docker hub上的mysql镜像创建mysql容器
docker hub上有官方的mysql镜像,我们可以利用它来创建mysql容器,作为一个服务容器使用. 1.下载mysql镜像 docker pull mysql 2.创建镜像 docker run ...
- 在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编
在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编 ...