理解 JavaScript 预解析_javascript技巧

事实上或某种现象证明并不是这样的,通过《JavaScript权威指南》及网上相关资料了解到,JavaScript有“预解析”行为。理解这一特性是很重要的,不然在实际开发中你可能会遇到很多无从解析的问题,甚至导致程序bug的存在。为了解析这一现象,也作为自己的一次学习总结,本文逐步引导你来认识JavaScript“预解析”,如果我的见解有误,还望指正。
(1)如果JavaScript仅是运行时自上往下逐句解析的,下面的代码能正确运行是可以理解的,因为我们先定义函数,然后才调用它。

复制代码 代码如下:

function showMsg()
{
alert('This is message');
}
showMsg(); // This is message

(2)我们也知道函数可以定义在调用代码之后,如下代码也是能正常工作的。看起来调用showMsg()的时候showMsg()还是没有定义的,但能正常工作,则表明JavaScript是“预解析”的。

复制代码 代码如下:

showMsg(); // This is message
function showMsg()
{
alert('This is message');
}

(3)上面是函数的例子,下面再来一个普通变量的例子。以下例子运行将会弹出undefined,表明第一句的msg已经是定义了,只是没有初始化,它与var msg; alert(msg);是一样的。如果你把下面第二句注释掉,则会报“msg未定义”错误。这亦表明JavaScript是“预解析”的。

复制代码 代码如下:

alert(msg); //undefined
var msg='This is message';

(4)再来看一个例子,加深对JavaScript“预解析”印象。以下代码你将看到两次弹出的对话框都是显示This is message 2,为什么会这样呢?其实下面一前一后定义了两个同名函数,后面的showMsg()覆盖了前面定义的(在JavaScript中,同名变量一样会存在覆盖问题),等于第一个showMsg()报废了。为什么第二次调用的showMsg()不是调用它上面定义的那个message 1函数呢?这再次证明JavaScript有“预解析”行为。

复制代码 代码如下:

showMsg(); // This is message 2
function showMsg()
{
alert('This is message 1');
}
showMsg(); // This is message 2
function showMsg()
{
alert('This is message 2');
}

(5)JavaScript“预解析”是把变量或函数预解析到它们能调用的环境(变量运行时环境)中。如下代码看起来alert(msg)之前有看到msg的定义,但是程序运行还是报“msg未定义”错误,这是因为函数里定义的变量是函数的私有变量,外面不能直接调用,这表明JavaScript“预解析”并不是把所有定义的变量统一解析到一个全局对象中,比如window。

复制代码 代码如下:

function showMsg()
{
var msg='This is message';
}
alert(msg); // msg未定义

(6)JavaScript“预解析”是分段进行的,准确说是分<script>块进行的。以下代码出现在同一个页面的两个脚本块中,同时定义了三个同名函数。程序运行结果表明第二个脚本块的showMsg()没有覆盖前面两个showMsg(),而第一个脚本块的第二个showMsg()则覆盖了第一个showMsg()。

复制代码 代码如下:

<body>
<script type="text/javascript">
showMsg(); //This is message 2
function showMsg()
{
alert('This is message 1');
}
function showMsg()
{
alert('This is message 2');
}
</script>
<script type="text/javascript">
function showMsg()
{
alert('This is message 3');
}
</script>
</body>

作者:WebFlash
出处:http://webflash.cnblogs.com

时间: 2025-01-31 01:47:54

理解 JavaScript 预解析_javascript技巧的相关文章

深入理解JavaScript定时机制_javascript技巧

例如 复制代码 代码如下: setTimeout(function() { alert('你好!'); }, 0); setInterval(callbackFunction, 100); 认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了. 同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不

JavaScript可否多线程? 深入理解JavaScript定时机制_javascript技巧

例如 复制代码 代码如下: setTimeout( function(){ alert('你好!'); } , 0); setInterval( callbackFunction , 100); 认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了. 同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行

理解JavaScript原型链_javascript技巧

每一个JavaScript对象都和另一个对象相关联,相关联的这个对象就是我们所说的"原型".每一个对象都会从原型继承属性和方法.有一个特殊的对象没有原型,就是Object.在之后的图示中会进行说明. 举个栗子,我们首先声明一个函数Student(): function Student(name){ this.name = name; this.hello = function(){ alert(`Hello,${this.name}`); } } 这个函数包含一个属性name和一个方法

扒一扒JavaScript 预解释_javascript技巧

带var关键字预解释 让我们先看下这段代码执行的结果: 复制代码 代码如下: alert(n);//弹出undefined var n = 10; 弹出的结果是undefined,为何不是10?让我们再看下面这段代码执行的结果: 复制代码 代码如下: alert(n); n = 10; 运行报如下错误: 为何这次会报错,原因是代码在运行的时候,没有声明这个变量n:通过这两段代码的比较,我们发现带var关键字和不带var关键字声明的变量是有区别的,带var声明的变量在代码执行之前,似乎浏览器已经给

用最通俗易懂的代码帮助新手理解javascript闭包 推荐_javascript技巧

最近看了几篇有关javascript闭包的文章,包括最近正火的汤姆大叔系列,还有<javascript高级程序设计>中的文章,--我看不懂,里面有些代码是在大学教科书中看都没看过的,天书一般.幸好最近遇到两本好书<ppk on javascript>和<object-oriented JavaScript>,正字阅读中,后者还没有中文版,但前者还是建议看原版,写的不复杂,有兴趣的朋友可以看看,适合想进阶的朋友. 今天就结合这两本书,用最浅显的语言和最通俗的方式谈谈jav

深入浅出理解javaScript原型链_javascript技巧

本文实例讲述了javaScript的原型链.分享给大家供大家参考.具体分析如下: 对于javascript原型链,以前都觉得是个很深的东西,一直没有理解很明白,今天看了一些介绍后,发现这张图,表示再没有什么语言能比这张图说得清楚了. 看了这张图后突然对javascript有了质的理解. javascript的原型链有显式和隐式两种: 显式原型链:即我们常见的prototype: 隐式原型链:在一般环境下无法访问,即不可见,在FireFox下可以通过__proto__方式访问:隐式原型链用于jav

理解javascript对象继承_javascript技巧

先从一个问题进行研究深入,什么是javascript对象继承? 比如我们有一个"动物"对象的构造函数. function animal() { this.type = '动物'; } 还有一个"猫"对象的构造函数. function cat(name,color) { this.name = name; this.color = color; } 我们知道猫也属于动物,如果这个猫对象想要继承动物对象的属性,我们该怎么做呢? 构造函数绑定 使用构造函数绑定是最简单的方

理解javascript异步编程_javascript技巧

一.异步机制 JavaScript的执行环境是单线程的,单线程的好处是执行环境简单,不用去考虑诸如资源同步,死锁等多线程阻塞式编程等所需要面对的恼人的问题.但带来的坏处是当一个任务执行时间较长时,后面的任务会等待很长时间.在浏览器端就会出现浏览器假死,鼠标无法响应等情况.所以在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应.所谓异步执行,不同于同步执行(程序的执行顺序与任务的排列顺序是一致的.同步的),每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一

理解JavaScript事件对象_javascript技巧

在触发DOM上的某个事件时,会产生一个事件对象event. DOM中的事件对象 兼容DOM的浏览器会将一个event对象传入到事件处理程序中.event对象包含与创建它的特定事件有关的属性和方法.除法的事件类型不一样,可用的属性方法就不一样.不过,所有的事件都会有下表列出的成员. 下面列出了 2 级 DOM 事件标准定义的属性: bubbles: 返回布尔值,指示事件是否是起泡事件类型. cancelable: 返回布尔值,指示事件是否可拥可取消的默认动作. currentTarget: 返回其