javascript的执行和预解析
很久以前遇到过一个面试题目,的的确确是面试官问我的问题,下面是这个问题的代码部分。由于年少无知,没有回答上,被无情pass了。
var u ='hello world';
;(function(){
alert(u);
var u = 'bonjour la monde';
})();
//请问alert的结果是什么?.
一开始毫不犹豫地想到 alert出来的是hello world; 面试官一脸无奈看着我,耸耸肩,我就大概知道被鄙视了。其实结果是undefined,但是一直没想通这样一个结果。后来才明白,JavaScript解析过程分为两个阶段,一个是预解析阶段,另外一个就是执行阶段。
执行阶段我们应该都很明白是什么意思
var u = 'hello world';
alert(u);
这段代码的结果是在浏览器中弹出出hello world不错,很简单,同样简单的还有下面的代码
alert(u);
var u = 'hello world';
结果是undefinded。因为u是在alert之后初始化的。所以按照从上到下的执行顺序来说,这样的结果是我们能够接受的。那么下面的代码呢?
u();
function u() {
alert('hello world');
}
结果是alert弹出hello world;这是为什么呢?u()明显地是在function函数上面先调用的,为什么函数能够执行呢?
其实在执行代码之前,浏览器会对js代码做预解析,解析的原则是这样的: 对该环境内用var声明变量进行提升到顶部的动作,并给它一个初始值undefined,同样,浏览器也会对function做提升动作,但是值是function返回的值,而不是undefined。并且按照命名唯一的原则,会将后声明的函数覆盖之前声明的同名函数上。如果你对上述说明不是很明白,我们可以换一种说法:浏览器在刷新的时候会悄悄地去执行。界面的js代码,不过它的执行方式是把所有在环境(window 或者 function)内声明的var 变了全部置顶并初始化为undefined。所以我们一开始面试官出题的代码在预解析之后可以等同于以下代码。
var u = 'hello world';
;(function(){}
var u;//或者var u = undefined;
alert(u);
u = 'bonjour la monde';
})();
有两个变量u,第一个是全局变量u,它是在window这个大环境内声明的,第二个是局部变量,它是在匿名函数function内声明的,因为匿名函数内包含着一个块级作用域,所以我们也可以说匿名函数内包含着一个不同于window的另一个环境。按照我们在上面提到的解析原则,在这个环境内的var变量都会提升到顶部,并且初始化为undefined,所以代码看起来就是上面的那个样子。而解析原则也会对函数提升,但是初始值不是undefined而是该函数本身,也就是说不会改变。那么下面两段代码可以说是同样的效果:
/解析前的函数
(function(){
say();
function say() {
alert('hello world');
}
});
//解析后的同效函数
(function(){
var say = function() {
alert('hello world');
}
say();
});
解析原则还包括对同名函数的覆盖,下面两段代码可以说明解析前后的状态。
//预解析前
(function () {
function say() {
alert('hello world');
} say() function say() {
alert('bonjour la monde');
}
})
//解析后的等效函数
(function(){
var say = function() {
alert('hello world')
}
var say = function() {
alert('bonjour monde')
} say();
});
现在,相信你应该对js的预解析过程有清楚的了解了。需要注意的是,用var和函数命名(function someFun())的方式声明一个函数都没有问题,这取决与项目的需要或者代码的规范或者个人的喜好,但是遇到以上的问题比如用var声明,那么在此之前你是不能够调用它的,而用function name() 方式命名,在同一个环境或者作用域内,你可以在任何地方调用它。
javascript的执行和预解析的更多相关文章
- javascript预解析和作用域
JavaScript解析过程分为两个阶段: 一是:编译阶段.就是JavaScrip预解析阶段,在这个阶段JavaScript解析器将完成把JavaScript脚本代码转换到字节码; 二是:执行阶段.在 ...
- js 预解析
前言 JavaScript是解释型语言是毋庸置疑的,但它是不是仅在运行时自上往下一句一句地解析的呢? 事实上或某种现象证明并不是这样的,通过<JavaScript权威指南>及网上相关资料了 ...
- JS预解析与变量提升
预解析 JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的.JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程 预解析过程 ...
- JavaScript-----11.预解析
1.预解析 1.1引子 //1问 console.log(num);//报错 num未定义 //2问 console.log(num); //undefined 未报错 var num = 10; / ...
- 第112天:javascript中函数预解析和执行阶段
关于javascript中的函数: 1.预解析:把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前 2.执行 :从上到下执行,但有例外(setTimeout,setInterval,aja ...
- javaScript中的小细节-script标签中的预解析
首先介绍预解析,虽然预解析字面意思很好理解,但是却是出坑出的最多的地方,也是bug经常会有的地方,利用好预解析的特性可以解决很多问题,并且提高代码的质量及数量,浏览器在解析代码前会把变量的声明和函数( ...
- js的预解析和代码执行相关规则
JavaScript解析过程分为两个阶段,一个是编译阶段,另外一个就是执行阶段. 1.编译阶段:又称为预解析阶段,在这个阶段JavaScript解释器将完成把JavaScript脚本代码转换到字节码. ...
- Javascript预解析、作用域、作用域链
最近在看js的一些资料,总结一下昨晚看到的js作用域方面的知识,不准确的地方希望留言指正! 先看片段js代码如下: < script type="text/javascript&quo ...
- JavaScript函数之作用域 / 作用链域 / 预解析
关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件 做一个有爱的搬运工~~ -------- ...
随机推荐
- 在 Linux 下将 PNG 和 JPG 批量互转的四种方法
计算机术语中,批处理指的是用一个非交互式的程序来执行一序列的任务[1]的方法.这篇教程里,我们会使用 Linux 命令行工具,并提供 4 种简单的处理方式来把一些 .PNG 格式的图像批量转换成 .J ...
- (python) 标准模块sys和os的使用
一.sys模块 包含了系统的相关的功能.我们来学习sys.argv,它包含命令行参数. 例子:定义了一个add函数,用来实现两个整数的相加. #! coding=utf-8 # usersys.py ...
- AngularJS 页面基本操作
一.避免预先加载angular模板语法 <style> [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, ...
- 修改Linux可显示的行数
在/boot/grub/menu.lst中,找到kernel开头的那一行,在后面加上参数vga=791 下面是vga可以取的值 # +----------------------------- ...
- Struts1 action重定向跳转 带参数
ActionForward forward = new ActionForward("kmRentalMain.do?method=view&fdId="+id);forw ...
- MIUI系统安全中心之自启动管理解密
迄今为止,Android系统的手机已经在整个手机市场中占有很大的比重.其中小米手机更是因为它的性价比和销售模式普遍的出现在了人们的日长生活中. 废话不多说,进入正题.作为一个Android的开发者,避 ...
- python基础整理笔记(七)
一. python的类属性与实例属性的注意点 class TestAtt(): aaa = 10 def main(): # case 1 obj1 = TestAtt() obj2 = TestAt ...
- .net framework 版本汇总
Version Release Date 1.0.3705.0 1RTM 2002/2/13 1.0.3705.209 1SP1 2002/3/19 1.0.3705.288 1SP2 2002/8/ ...
- HDU 2068 RPG的错排
要求答对一半或以上就算过关,请问有多少组答案能使他顺利过关. 逆向思维,求答错一半或以下的组数 1,错排 错排公式的由来 pala提出的问题: 十本不同的书放在书架上.现重新摆放,使每本书都不在原来放 ...
- idea中maven报错:无效的目标发行版: 1.8
1.project.pom中修改版本 <maven.compiler.source>1.7</maven.compiler.source><maven.compiler. ...