JavaScript是一门有趣的语言,不仅有趣而且调皮,不同的内核的浏览器在解析的时候表现会有些差异,今天主要是抛砖引玉,和大家一起讨论一些在实际开发中比较常见但同时可能并没有过于在意的JavaScript表现。这里先做几个约定: 由于JavaScript是一门解释性语言,自然没有编译过程,但在脚本执行之前会有语法检查和执行环境的构建,我们把这一过程姑且称为预处理吧。
当使用var关键字来声明一个变量或者函数时,我们把这一过程称为变量声明和函数声明,当使用表达式形如function fn() = {}来定义一个函数的方式称为函数定义。
文中实例的测试环境是我电脑上安装的IE9、FF4.0、chrome 14.0三个不同内核的浏览器。
好吧,接下来进入正题,主要看一些简单的demo来观察和了解浏览器是怎样初始化JavaScript中的变量以及函数,主要涉及到的点包括JavaScript中的作用域以及执行环境,对这方便不是很了解的朋友可以参考文章最后的相关链接,看一些简单的demo吧。
DEMO1、函数声明
 
 
这个能说明什么呢?第一次调用fn时访问的是通过函数定义的方法,第二次调用访问的是通过函数定义的方法,那么这整个过程从预处理到执行完毕是谁覆盖了谁,谁的优先级更高呢?带着这个疑惑接着测试。
DEMO2、 关于局部变量和全局变量的访问
 
 
 
这里在fn方法中依次输出了四个变量,不知道结果和你预期的有没有差异,输出的第一个参数num1在局部和全局环境中都有声明,局部变量优先级高于全局变量无可厚非,这里不一样的是在声明变量之前访问了num1,说明在预处理阶段构造执行环境时已经为局部变量分配了存储空间,赋的初始值是undefined罢了,输出的第二个变量num3在arguments和局部变量中都有,输出的是arguments中的参数变量,如果前面一个结论成立,那么说明arguments中的变量覆盖了局部环境中的变量,也就是说通过变量定义的方式优先级高于arguments对象数组中定义的变量。第三个输出num4时会报错误,说明连续赋值操作中除第一个变量以外的变量被视为全局变量处理,而全局环境中没有相关定义所以会出错,第四个num2输出出错也是由于被视为全局变量的原因,这两个地方的错误应该可以引用这样一句话:“个人自扫门前雪,莫管他人瓦上霜”,也就是说预处理阶段一个独立的执行环境只会维护自己内部的变量,忽略其他环境的变量。
DEMO3、函数的调用
 
 
 
这个demo主要目的是比较arguments、函数定义和函数声明三种方式的一个优先级,从结果知道输出的是通过函数声明的方式定义的函数,从上一个实例得出的结论是arguments中变量会覆盖var方式定义的变量,这里arguments中的变量又被函数定义的方法覆盖了,那我们可以得到这样一个结论:将函数声明为变量(var t = function(){})的方式优先级最高,在预处理阶段被初始化,执行时会先被arguments中的变量覆盖,最后被通过函数定义(function t(){})创建的变量覆盖,这一过程完毕后程序才开始执行。
众所周知JavaScript中没有块级作用域,浏览器间也是表现一致的,比如以下代码:
 
 
 
好吧,在这一点上没有任何疑问,那接下来继续看下面一段代码:
DEMO4
 
 
 
这段代码的输出是什么呢,我觉得不防自己测试下,在IE中和chrome中会输出”function fn(){return 2;}”,在FF中是会报错的,那如果代码改成:
 
 
 
输出的结果在IE和chrome中没有变化,在FF中变成了”function fn(){return 1;}”,这个结果可能和你之前预想的不太一样,我在网上看了一些网站对此也有不同的说法,有些说是FF的bug,个人觉得不应该算bug,毕竟每一个浏览器厂商在实现ECMAScript的标准时会有差异,不能因为和大多数人实现的不一样,就把自己视为错误吧。那为什么会出现这种差异呢,个人觉得是在预处理阶段构建执行环境时对块状作用域的处理上有一些差异,首先先确认一点,如果在块级作用域中通过var关键字声明一个变量,那么不管在声明语句之前还是之后访问该变量都是没有问题的,因为在构建执行环境时会找出所有本域中通过var定义的变量并分配空间,但是通过函数定义的方式就不一样了,IE和chrome会在构建的时候初始化函数对象,并且后面的定义会覆盖前面的定义,从上面的代码还可以看出一点,由于在预处理阶段已经处理了函数定义,在代码的执行阶段不管代码逻辑如何都会直接忽略函数的定义(这点很重要),而在FF中预处理时会忽略块级作用域中的函数定义,在代码执行时再进行初始化,两种实现方式从性能和效率上来说个人感觉FF的实现方式更合理一些,所以不能把这种实现方式归类于bug,当然纯属个人观点。
DEMO5、关于命名函数表达式
 
 
 
先看一下结果,在IE8及以下版本中输出的true,IE9、FF以及chrome中输出的是false。好吧,先讨论下命名函数表达式,格式如下:
 
 
 
在声明一个函数的同时为其指定一个别名,这个别名在IE8及以下版本中在外部是可以访问的,在IE9、FF或者chrome中只能在函数内部访问,这就是为什么会出现DEMO5中那样的情况了,在外部可以访问会造成诸多问题,比如变量名污染等,所以建议在实际开发中不采用这种写法。
好了,瞎扯了这么多,大牛就一笑而过吧。最后还是简单的总结下,在做前端开发的时候,了解浏览器解析JavaScript的过程对写出规范的代码是很有必要的,这样可以减少一些不必要的错误,以后再继续探讨这些有趣的问题。
 
 
本文转载自分针网

分针网—IT教育:调皮的JavaScript的更多相关文章

  1. 分针网—IT教育: jquery选择器的用法

    jQuery选择器是jQuery库的一大特色,用这些选择器不但可以省去繁琐的JavaScript 书写方式,还可以节省时间和效率,正是有这些jQuery选择器,才让我们更容易的操作JavaScript ...

  2. 分针网—IT教育: Html / CSS常见问题的解决方案

    1. 解决Safari下input光标过大   2. 设置浮层   3. CSS绘制三角形   4. 清除浮动   1) 浮动元素父级添加样式   2) 父元素后添加伪元素     3) 同样可以使用 ...

  3. 分针网—IT教育:作为PHP开发人员容易忽视的几个重点

    无论是学习什么样的一个开发.ASP开发.java开发.当学习还不是很久的时候,一般都是不知道它们的精华是在哪里,而现在很多的php程序员也是不知道PHP的精华所在,为什么perl在当年在商界如此的出名 ...

  4. 分针网—IT教育:使用CSS3制作导航条和毛玻璃效果

    导航条对于每一个Web前端攻城狮来说并不陌生,但是毛玻璃可能会相对陌生一些.简单的说,毛玻璃其实就是让图片或者背景使用相应的方法进行模糊处理.这种效果对用户来说是十分具有视觉冲击力的.本次分享的主题: ...

  5. 分针网—每日分享: 怎么轻松学习JavaScript

    js给初学者的印象总是那么的"杂而乱",相信很多初学者都在找轻松学习js的途径.   我试着总结自己学习多年js的经验,希望能给后来的学习者探索出一条"轻松学习js之路& ...

  6. 分针网—每日分享:HTML解析原理

    标准的web前端工程师需要知道 ◎浏览器(或者相应播放器)的渲染/重绘原理   这我得加把劲了.我还真的说的不是很清楚,我就G下,结果不是很多,找到了有一个,就记下来了...   以下部分来自hand ...

  7. 分针网——每日分享: jquery选择器的用法

    jQuery选择器是jQuery库的一大特色,用这些选择器不但可以省去繁琐的JavaScript 书写方式,还可以节省时间和效率,正是有这些jQuery选择器,才让我们更容易的操作JavaScript ...

  8. 【模拟,时针分针秒针两两夹角】【没有跳坑好兴奋】hdu - 5387 (多校#8 1008)

    算是最好写的一道题了吧,最近模拟没手感,一次过也是很鸡冻o(* ̄▽ ̄*)o 注意事项都在代码里,没有跳坑也不清楚坑点在哪~ #include<cstdio> #include<cst ...

  9. Android_模拟时钟内时针、分针触摸转动

    最近实现了android里的一个机能,在activity里面画了一个模拟的时针,然后触摸上面的时针跟分针可以实现调时间的功能. 其实,说起原来来还是挺简单的,但是我花了将近一周的时间才全部实现,有点惭 ...

随机推荐

  1. linux 根分区扩展

    linux根分区扩容 今天网站上传图片出问题了,一开始还以为是程序问题,后来发现原来是服务器存储空间不够,明明有200G的磁盘空间,没理由这么快就用完,查了一下分区情况,原来有两块磁盘,根分区只挂载在 ...

  2. Map集合概述和特点

    A:Map集合概述和特点(Set底层依赖的是Map) 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 B:Map接口和Collection接口的不同 Map是双列的(是双列集 ...

  3. 10大支持移动“触摸操作”的JavaScript框架

    摘要:移动开发行业的发展速度让人目不暇接,也在此大势之下,推出移动网站App成为开发者必经之路,如何让触屏设备 更易使用?如何让网站对触摸手势做出反应并使触摸更友好?所有这一切,皆因JavaScrip ...

  4. js华氏度转为摄氏度

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Think In Java_读书笔记_042516

    面向对象程序设计方式: 1, 万物皆对象. 2,程序是对象的集合,他们通过发送消息来告知彼此所要做的.(个人理解,比如你调用方法的时候需要去调用某个对象的某个方法,必须传相应的参数,这些参数列表就相当 ...

  6. API的文档自动生成——基于CDIF的SOA基本能力

    当前,作为大部分移动app和云服务后台之间的标准连接方式,REST API已经得到了绝大部分开发者的认可和广泛的应用.近年来,在新兴API经济模式逐渐兴起,许多厂商纷纷将自己的后台业务能力作为REST ...

  7. VB中的GDI编程-1 设备环境DC

    p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...

  8. 测试开发Python培训:抓取新浪微博评论提取目标数据-技术篇

    测试开发Python培训:抓取新浪微博评论提取目标数据-技术篇   在前面我分享了几个新浪微博的自动化脚本的实现,下面我们继续实现新的需求,功能需求如下: 1,登陆微博 2,抓取评论页内容3,用正则表 ...

  9. JavaScript原生Array常用方法

    JavaScript原生Array常用方法 在入门Vue时, 列表渲染一节中提到数组的变异方法, 其中包括push(), pop(), shift(), unshift(), splice(), so ...

  10. selenium自动化过程中如何操作Flash动画

    最近在看python的爬虫框架(scrapy),一个词概括就是:"酸爽"!等把selenium自动化版块讲完后,打算写一写关于scrapy相关的知识,打算从源码角度解析下scrap ...