'Javascript' 的档案


易让人忽视的JavaScript陷阱

从1996年网景公司第一次介绍JavaScript,这门语言自今已经有了10多年的历史了,随着互联网技术的发展,JavaScript也从诞生时只完成简单的表单验证发展成互联网上非常重要的一门语言,用它开发的网络应用已经五花八门,许多产品的功能已经接近了桌面产品。尽管JavaScript语言的重要性在不断的提升,可是它的语言内核基本上没有发生太大变化。

由于JavaScript这门语言在设计上有些地方存在缺陷,或者我们对一些技术点的理解不透彻,会导致编程过程中出现一些脚本语言层面的bug,这类bug往往非常隐蔽,要排查这类bug所花的时间往往也非常多。 详情 »

显示JavaScript函数调用堆栈的方法

许多大型的JavaScript应用程序间的函数调用关系是非常复杂的,在开发或者调试过程中,经常需要跟踪某个函数是由哪些函数调用后才触发执行的,弄清楚这些函数的调用顺序对我们理解代码的数据流向是非常重要的。

Firebug提供了console.trace()来显示函数堆栈,在需要调试的地方加上下面的一行代码就能显示该函数调用时的上下文关系。IE6就没有这么方便了,它没有提供显示函数堆栈的工具, 详情 »

编写高压缩比的JavaScript代码

网站发布前的JavaScript代码压缩是大部分Web前端工程师必做的一项工作,常用的JavaScript压缩工具有Dean Edwards写的JavaScript CompressorYUI CompressorClosure Compiler。本文中列出的编码原则是笔者在编程过程中总结出来的十条原则,这些原则适用于一般的JavaScript压缩工具,不适用于Closure Compiler的高级模式(由于Closure Compiler的高级模式过于智能,会用最优的方式重新组织代码结构)。 详情 »

理解Closure Compiler强加的约束

Closure Compiler期望输入的JavaScript符合一定的约束条件。压缩级别越高,约束条件越多。

本文分别介绍每种级别的条件约束。

适用于所有级别的约束

下面两条约束条件适用于Closure Compiler(以下简称“编译器”)的所有级别压缩:

  • 编译器只能识别Ecmascript 262第三版
    Ecmascript第三版是Javascript 1.5 和 JScript 5.5的基础,当人们提到“JavaScript”时,通常指的是这个版本的JavaScript。编译器不支持任何版本的JScript或者高于1.5版本的JavaScript。

    符合Ecmascript语言规范的浏览器特有特性能够很好的在编译器中工作,例如用合法JavaScript语法创建的ActiveX对象;不符合Ecmascript语言规范的浏览器特有特性会导致编译器错误,例如,Firefox的JavaScript引擎支持const关键字,但JavaScript规范中没有包含这个关键字,所以编译器不支持它。本约束能让编译器检查代码是否兼容所有浏览器。

  • 编译器不保留注释
    选择编译器的任何级别压缩都会删除代码中的注释,所以那些依赖特定注释的代码不能用编译器来压缩。

    举个例子,因为编译器不会保留代码注释,所以代码中不能直接使用JScript的条件化注释,然而,你可以使用eval()将代码中的条件化注释包起来,编译器可以正确的压缩下面的代码:

    JAVASCRIPT:
    1. x = eval("/*@cc_on 2+@*/ 0");

    提示:你可以使用@preserve annotation参数在压缩后的代码顶部包含如开源代码授权或者其它重要的文字。

详情 »

Closure Compiler三种压缩级别

Closure Compiler(以下简称“编译器”)提供三种不同级别的压缩模式。

WHITESPACE_ONLY(去空白优化)

该级别会删除代码中的注释、换行符和其他不必要的空格,输出后的代码在功能上和压缩前的代码完全一样。该压缩级别是三种级别中代码压缩最小的。

SIMPLE_OPTIMIZATIONS(简单优化)

该级别包含WHITESPACE_ONLY级别的所有功能,此外,它还提供用短名称重命名局部变量名和函数参数名的功能。用短名称重命名变量可以让代码体积明显的减少。由于该级别压缩只是对函数内部的局部变量重命名,所以不会影响被压缩代码与其他(未用Closure Compiler压缩的)JavaScript代码之间的相互调用。编译器还提供对JavaScript语法验证的功能,只要该代码不使用字符串名称访问本地变量(例如使用eval())。

该级别是编译器默认的压缩级别。

ADVANCED_OPTIMIZATIONS(高级优化)

该级别包含SIMPLE_OPTIMIZATIONS级别的所有功能,另外,它还添加了许多入侵性代码转换,从而实现三种级别中最高压缩比。使用该级别压缩代码能超越其它JS代码压缩工具(如YUI Compressor),达到最好的代码压缩效果。

为了使用这种极端压缩方式,ADVANCED_OPTIMIZATIONS要求代码在编写时遵循很强的约定。如果代码没有遵从这些约定,那么使用该级别生成的代码将不能运行。

例如,除非对压缩的代码完成某些确保互操作性的指定步骤,否则使用ADVANCED_OPTIMIZATIONS压缩后的代码有可能不能和未压缩的代码一起运行。如果没有对代码中的外部函数引用和外部属性引用做标识,编译器会对这些引用重命名,从而产生压缩代码和外部代码间名称不一致的错误。

更多相关内容请看使用Closure Compiler高级模式需要注意哪些问题?

ADVANCED_OPTIMIZATIONS会对代码做以下转换:

  • 更多侵入性的重命名
    SIMPLE_OPTIMIZATIONS只会对函数参数和函数内部变量重命名,而ADVANCED_OPTIMIZATIONS还会对全局变量、函数名、属性名重命名。
  • 删除无用代码
    ADVANCED_OPTIMIZATIONS会删除未使用的代码。当代码和一个很大的JS库一起压缩时,这个功能特别有用。如果代码只用到类库中的小部分函数,编译器输出时会将类库中除这小部分函数外的其它函数都删除。
  • 内联函数(inlining)
    ADVANCED_OPTIMIZATIONS会将一些调用函数替换为函数体内容,这种转换被称为“内联函数”,编译器只会对那些它检查后认为安全的函数做内联函数,另外,它还会对它认为安全的常量或变量使用内联方式。

下一页 »