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函数之作用域 / 作用链域 / 预解析
关于作用域和作用链域的问题,很多文章讲的都很详细,本文属于摘录自己觉得对自己有价值的部分,留由后用,仅供参考,需要查看详细信息请点击我给出的原文链接查看原文件 做一个有爱的搬运工~~ -------- ...
随机推荐
- 在Mac上搭建本地Apache服务器一些注意点
一般在开发ios程序中,我们需要使用到和服务器的交互操作. 一般我们在Mac上使用Apache来搭建服务器.数据库采用MySQL.在Mac中Apache是自带的.所有,我们可以不需要额外的去Apple ...
- odoo 10 生产自动领料
分析源码 当 原材料的 补货规则 的 "补货位置" location_id 是 生产单 的 原材料 "目标位置 ", 并且 原材料的 补货规则 的 " ...
- python操作系统环境变量
获取整个系统变量的方法是os.environ,这是一个os的class类型,使用的时候可以转换为字典类型 environ_value = dict(os.environ) 这样就可以看所有的key,e ...
- NLS_LANG
NLS_LANG是一个环境变量,用于定义语言,地域以及字符集属性.对于非英语的字符集,NLS_LANG的设置就非常重要. NLS:‘National Language Support (NLS)’ 当 ...
- python第一天基础1-2
python入门 1 第一个python代码: 在linux上创建第一个.py脚本 #!/usr/bin/env python #-*- coding:utf-8 -*- print "He ...
- Eclipse在线集成maven M2eclipse插件
首先说下版本: Eclipse:3.6 Maven:3.3.1,若不知道如何在本地安装Maven,请参见我的另一篇文章:Window下安装Maven 废话少说,直接讲步骤就好: 1.打开eclipse ...
- Linux 如何使用压缩与解压缩的方式将Windows下的zip压缩包上传到Linux系统
当我们无法使用xftp方式上传文件到Linux系统时,我们可以使用在Windows下压缩文件夹,然后到Linux系统下解压缩的方式,完成整个上传工作. 第一步:在Windows系统下,将整个文件夹压缩 ...
- hdu 1312(DFS)
Red and Black Tme Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- Web前端学习路线
第一阶段: HTML+CSS:HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础:Js基础教程.js内置对象常用方法.常见DOM树操作大全.ECMAsc ...
- python+selenium+Robot
准备工作: 1.下载python2.7 http://python.org/getit/ 2.下载下载setuptools [python 的基础包工具] 可以帮助我们轻松的下载,构建,安装,升级,卸 ...