标签 javascript 下的文章

JavaScript 高程设计——基本概念

语法

严格模式

"use strict";

关键字和保留字

关键字

break   case    catch   continue    default delete  
do  else    finally for function    if  in  instanceof  
new return  switch  this    throw   try typeof  
var void    while   with    debugger*

保留字

abstract    boolean byte    char    class   const   
debugger    double  enum    export  extends final   
float   goto    implements  import  int interface   
long    native  package private protected   public  
short   static  super   synchronized    throws  
transient   volatile    let yeid

数据类型

ECMAScript 中有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String。

还有一种复杂数据类型——Object。

鉴于 ECMAScript 是松散类型的,因此需要有一种手段来检测给定变量的数据类型—— typeof 就是负责提供这方面信息的操作符。

null == undefined
// true

永远不要测试某个特定的浮点数值。

ECMAScript 能够表示的最小值保存在 Number.MIN_VALUE 中——在大多数浏览器中,这个值是5e-324;能表示的最大数值保存在 Number.MAX_VALUE 中。超出此范围使用 Infinity-Infinity 值。使用 isFinite() 函数判断是否在此范围内。

NaN 本身有两个非同寻常的特点。首先,任何涉及 NaN 的操作都会返回 NaN,这个特点在多步计算中有可能导致问题。其次,NaN 与任何值都不相等,包括 NaN 本身。使用 isNaN() 函数。

parseInt()/parseFloat()parseFloat(),十六进制格式的字符串则始终会被转换为0。

ECMAScript 中的字符串是不可变的,也就是说,字符串一旦被创建,它们的值就不能改变。

Object 的每个实例都具有下列属性和方法:ConstructorhasOwnProperty(propertyName)isPrototypeOf(object)propertyIsEnumerable(propertyName)toLocaleString()toString()valueOf()

ECMA-262 不负责定义宿主对象,因此宿主对象可能会也可能不会继承 Object

操作符

逗号操作符还可以用于赋值。在用于赋值时,逗号操作符总会返回表达式中的最后一项。

// num的值为0
var num = (5, 1, 4, 8, 0);

语句

for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。以下是for-in 语句的语法:

for (property in expression) statement

for (var propName in window) {     
    document.write(propName);
}

with 语句的作用是将代码的作用域设置到一个特定的对象中。with 语句的语法如下:

with (expression) statement;

with(location){    
    var qs = search.substring(1);    
    var hostName = hostname;    
    var url = href;
}

可以在 switch 语句中使用任何数据类型(在很多其他语言中只能使用数值),无论是字符串,还是对象都没有问题。其次,每个 case 的值不一定是常量,可以是变量,甚至是表达式。

switch 语句在比较值时使用的是全等操作符,因此不会发生类型转换。

函数

关于 arguments 的行为,还有一点比较有意思。那就是它的值永远与对应命名参数的值保持同步。不过,这并不是说读取这两个值会访问相同的内存空间;它们的内存空间是独立的,但它们的值会同步。但这种影响是单向的:修改arguments[0]的值会自动同步到命名参数中;而修改命名参数不会改变 arguments 中对应的值。另外还要记住,如果只传入了一个参数,那么为 arguments[1] 设置的值不会反应到命名参数中。这是因为 arguments 对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数的个数决定的。

ECMAScript 中的所有参数传递的都是值,不可能通过引用传递参数。

JavaScript 高程设计——在HTML中使用 JavaScript

<script> 元素

HTML 4.01 为 <script> 定义了以下6个属性:

  • async:可选。表示应该立即下载脚本,但不应妨碍页面中的其他操作。只对外部脚本文件有效;
  • charset:可选。表示通过 src 属性指定的代码的字符集。很少有人用这个属性;
  • defer:可选。表示脚本可以延迟到文档完全被解析和显示之后再执行;
  • language:已废弃;
  • src:可选。表示包含要执行代码的外部文件;
  • type:可选。表示编写代码使用的脚本语言的内容类型;目前 type 属性的值依旧还是 text/javascript。不过这个属性并不是必须的,因为没有指定时默认值也是 text/javascript

在使用 <script> 元素嵌入 JavaScript 代码时,不要在代码中的任何地方出现 "</script>"字符串。按照接卸嵌入式代码的规则,当浏览器遇到字符串 "</script>" 时,就会认为是结束的 </script>标签。而通过转义字符 “\” 可解决这个问题:"<\/script>"。例如:

<script>
    function sayScript(){
        alert("<\/script>");
    }
</script>

在引入外部文件时,只能像下面这样写:

<script type="application/javascript" src="example.js"></script>

而不能使用如下形式:

<script type="application/javascript" src="example.js"/>

引入了外部文件的 <script> 元素不能再嵌入代码,嵌入的代码将会被忽略,只外部文件起作用。

无论如何包含代码,只要不存在 deferasync 属性,浏览器都会按照 <script> 元素在页面中出现的先后顺序对它们依次进行解析。

标签的位置

现代 Web 应用程序一般都把全部的 JavaScript 引用放在 元素中页面内容的后面。如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
</head>
<body>


<script src="example.js"></script>
</body>
</html>

延迟脚本

使用 defer 属性,相当于告诉浏览器立即下载,但延迟执行。IE4/Firefox3.5/Safari5/Chrome 是最早支持此属性的浏览器,其他浏览器会忽略此属性,因此把延迟脚本放在页面底部仍然是最佳选择。使用例子:

<script defer src="example.js"></script>

异步脚本

HTML 5 为 <script> 元素定义了 async 属性。这个属性与 defer 属性类似,都用来改变处理脚本的行为;但与 defer 属性不同的是,标记为 async 脚本并不保证按照指定它们的先后顺序执行。指定 async 属性的目的不是让页面等待两个脚本下载和执行,从而异步加载页面其他内容。因此,建议异步脚本不要在加载期间修改 DOM。异步脚本一定会在页面的 load 事件前执行。

<script async src="example.js"></script>

文档模式

IE 5.5 引入了文档模式的概念,而这个概念是通过使用文档类型(doctype)切换实现的。最初的两种文档模式是:混杂模式(quirks mode)和标准模式(standards mode)。这两种模式主要影响 CSS 内容的呈现,但在某些情况下也会影响 JavaScript 的解释执行。在此之后,IE 又提出一种所谓的准标准模式(almost standards mode)。

如果文档开始处没有发现文档类型声明,则所有的浏览器都会默认开启混杂模式;对于标准模式可以通过使用下面任何一种文档类型来开启:

<!-- HTML 4.0.1 严格型 html:4s -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- HTML 5 !-->
<!DOCTYPE html>

而对于准标准模式,则可以使用过渡型(transitional)或框架集型(frameset)文档类型来触发:

<!-- HTML 4.0.1 过渡型 html:4t -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">
<!-- HTML 4.0.1 框架集型 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" 
    "http://www.w3.org/TR/html4/frameset.dtd">

<noscript> 元素

<body> 中使用此元素。

JavaScript 高程设计——JavaScript 简介

JavaScript 诞生于1995年。当时,它的主要目的是处理以前由服务器端语言负责的一些输入验证操作。如今,JavaScript 的用途早已不再局限于简单的表单验证,而是具备了与浏览器窗口及其内容等几乎所有方面交互的能力。JavaScript 已经成为一门功能全面的编程语言,能够处理复杂的计算和交互,拥有了闭包、匿名函数(lamda,拉姆达),甚至元编程等特性。

JavaScript 从一个简单的输入验证器发展成为一门强大的编程语言,完全出乎人们的意料。应该说它既是一门非常简单的语言,又是一门非常复杂的语言。

JavaScript 简史

Netscape 公司,布兰登·艾奇(Brendan Eich),Navigator 3 / Internet Explorer 3

1997年,以JavaScript 1.1 为蓝本,ECMA(欧洲计算机制造商协会)的 TC39 (39号技术委员会)负责对其标准化,最终发布 ECMA-262。

JavaScript 实现

一个完整的 JavaScript 实现应该由下列三个不同的部分组成:

  • 核心(ECMAScript)
  • 文档对象模型(DOM)
  • 浏览器对象模型(BOM)

ECMAScript

由 ECMAScript-262 定义的 ECMAScript 与 Web 浏览器没有依赖关系,后者只是其实现可能的宿主环境之一。其他宿主环境包括 Node 和 Adobe Flash。

ECMAScript 定义了以下内容:语法、类型、语句、关键字、保留字、操作符和对象。

最新版:ECMAScript-262 的第5个版本于2009年12月发布

兼容性:IE 5.5~7 兼容第3版,IE 8+ 兼容第5版,其他主流浏览器一般都兼容第3版。

DOM

文档对象模型(DOM)是针对 XML 但经过扩展用于 HTML 的应用程序编程接口。DOM 将整个页面映射为一个多层节点结构。

一开始,IE 4 和 Navigator 4 分别支持不同形式的 DHTML ,浏览器互不兼容。此时,负责 Web 通信标准的 W3C (万维网联盟)开始着手规划 DOM。

DOM 级别:DOM 1 级实现了映射文档结构,DOM 2 级扩展了,DOM 3 级进一步扩展了。

浏览器支持:IE 5.5~8 1级,IE9 + 1级、2级、3级,Chrome 1+ 1级、2级,Firefox 1+ 1级、2级、3级。

BOM

浏览器对象模型支持可以访问和操作浏览器窗口,可以控制浏览器显示的页面以外的部分。BOM 没有相关标准,直到 HTML 5 才将 BOM 正式规范化。例如下面的扩展都属于 BOM :

  • 弹出窗口功能
  • 移动、缩放和关闭浏览器窗口的功能
  • 提供浏览器详细信息的 navigator 对象
  • 提供浏览器所加载页面的详细信息的 location 对象
  • 提供用户显示器分辨率详细信息的 screen 对象
  • 对 cookie 的支持
  • 像 XMLHttpRequest 和 IE 的 ActiveXObject 对象

每一天当成是末日来对待

The Time.jpg

自己准备了几本书,打算把 JavaScript 系统的学习一下,有《JavaScript 高级程序设计》、《JavaScript 语言精粹》和《JavaScript 设计模式》,甚至还有《Node.js 深入浅出》。可以有这么多书看了,兴奋到不行。从高级程序设计和Node开始看,大部分都在公交车上看。早晨八点出门,坐428路两站,下来再做985/984/617等,回来的时候坐464,路程大约在40分钟内。在很多时候是没有座位的,也就没法看书了。可即使如此,一周下来竟然把Node看完了,当然读书的质量并不高,但至少是一字一句看下来的。果然,时间不是没有,时间就像海绵里的水,挤挤总会有的。

计算一下,人生不过两万天,几亿秒,生活和工作也是由这一分一秒构成的。说这样的道理人人都懂,可是真正去珍惜的人少之又少。有人在地铁在路口在去吃饭的路上感叹:在北京的人这么多,人才多的是,自己怎样才能从里面混出个样来呢?其实答案很简单,就是比每个人更珍惜每一天,每一天的每一分每一秒即可。

使用 JSDoc 3 自动生成 JavaScript API 文档

软件并不只是包括可以在计算机上运行的电脑程序,与这些电脑程序相关的文档,一般也被认为是软件的一部分。简单的说软件就是程序加文档的集合体。

随着项目的升级进化,前端产生的 JavaScript 代码越来越多越复杂;同时,也有越来越多的 JavaScript 问题出现,其中 JavaScript 文档的编写和维护成为一个亟待解决的难题。

许多现代编程语言都有自己的集成化文档生成工具,像 Java 有 JavaDoc ,.NET 有 NDoc,PHP 有 PHPDoc,这些自动化文档工具可以根据代码中的注释自动生成代码文档。本文将介绍的 JSDoc 也是这样的工具。

简介

JSDoc 3 是 JsDoc Toolkit 的升级版本,JsDoc Toolkit 是一个自动化文档工具,它是发布在 Google code 上的一个开源项目,和其他语言的文档工具一样,它可以自动从 JavaScript 代码中提取注释生成格式化文档。从 2010年7月27日 开始,JsDoc Toolkit 2 已经停止开发了,因此如果要使用 JSDoc 的话,还是推荐采用 JSDoc 3。现在 JSDoc 3 代码托管在 GitHub 上,项目地址:https://github.com/jsdoc3/jsdoc

安装

JSDoc 3 在本地安装依赖于 Nodejs,因此首先需要下载 Nodejs 进行安装:

http://nodejs.org/
http://nodejs.org/dist/v0.10.25/x64/node-v0.10.25-x64.msi

安装完后,使用以下命令安装 JSDoc 3 即可(:必须使用超级管理员身份安装):

# stable
npm install jsdoc@"<=3.3.0" -g
# dev
npm install git+https://github.com/jsdoc3/jsdoc.git -g

# test
C:\Users\moodpo>jsdoc --help
JSDoc 3.3.0-alpha3 (Wed, 25 Dec 2013 17:07:35 GMT)
......

使用

JSDoc 3 生成 API 文档完全依赖于你的代码注释,因此了解 JSDoc 3 的注释规则是最重要的。首先,注释必须要以 /** 开头,如果使用 /* 将不被识别;其次,每个注释块都应该包含唯一的主标签,和零个或多个副标签。

1. JSDoc 3 标签规范

标签 描述
@abstract/@virtual This member must be implemented (or overridden) by the inheritor.
@access Specify the access level of this member - private, public, or protected.
@alias Treat a member as if it had a different name.
@augments/@extends 标明一个函数继承另一个函数,如 A 继承 B 则可以在 A 的注释中加 `@augments B`
@author Identify the author of an item.
@borrows 参考,如 A 和 B 两个函数意义相同,则可以在 B 的注释中加 `@borrows A as B`,而不需重复添加注释
@callback/@typedef 标明此方法是一个回调函数
@classdesc 对一个类的描述
@constant/@const 常量标识
@constructor/@class 标明是构造器函数,可使用 `new` 关键字实例化
@constructs 当使用对象字面量形式定义类时,可使用此标签标明其构造函数
@copyright 描述版权信息
@default 默认值
@deprecated 弃用
@desc/@description 如果在注释开始描述可省略此标签
@enum 一个类中属性的类型相同时,使用此标签标明
@event 标明一个可触发的事件函数,一个典型的事件是由对象定义的一组属性来表示。
@example 示例,代码可自动高亮
@exports 标识此对象将会被导出到外部调用
@external/@host 标识此类、命名空间或模块来自外部
@file 描述文件功能
@fires/@emits 标明当一个方法被调用时将出发一个特殊类型的事件
@global 全局变量标识
@ignore 忽略此注释块
@inner 标明此代码是父类的内部变量
@instance 标明此代码是父类的实例
@kind 标明代码在其文档中的类型,如Class、Modual等
@license 采用的开源协议版本
@link 内联标签,创建一个链接,如 `{@link http://github.com Github}`
@member/@var 记录一个基本数据类型的成员变量
@memberof 指定一个变量所属的父类
@method/@function/@func 标记一个方法或函数
@mixes 标记一个对象混合了另一个对象的所有成员
@mixin 一个 `mixin` 提供了旨在将方法添加到对象上的功能
@module 标明当前文件模块,在这个文件中的所有成员将被默认为属于此模块,除非另外标明
@name 指定一段代码的名称,强制 JSDoc 使用此名称,而不是代码里的名称
@namespace 指定一个变量为命名空间变量
@param 标记方法参数及参数类型
@private/@protected/@public 标明变量访问等级
@property 标明一个对象的属性
@readonly 只读
@requires 标明运行代码所需模块
@returns/@return 标明返回值、类型及描述
@see 链接到一个参考位置
@since 描述此功能来自哪一版本
@static 描述一个不需实例即可使用的变量
@summary 对描述信息的短的概述
@this 说明 `this` 关键字所代表的意义
@throws 描述方法将会出现的错误和异常
@todo 描述函数的功能或任务
@tutorial 插入一个指向向导教程的链接
@type 描述代码变量的类型
@version 版本信息

更多内容请查看官方文档

2. 使用 conf.json 文件

安装完 JSDoc 3 后默认使用的配置文件为 conf.json.EXAMPLE,内容如下:

{
    "tags": {
        "allowUnknownTags": true
    },
    "source": {
        "includePattern": ".+\\.js(doc)?$",
        "excludePattern": "(^|\\/|\\\\)_"
    },
    "plugins": [],
    "templates": {
        "cleverLinks": false,
        "monospaceLinks": false
    }
}

我们可以定义自己的 conf.json 文件,使用此文件可以指定 JSDoc 输出目录、命令行操作参数、使用的插件、输出模版以及读取的文件等,以下是完整的文件内容:

// 使用时请删除所有注释
{
    "tags": {
        "allowUnknownTags": true //允许输出位置标签
    },
    "source": { // 指定读取的源文件
        "include": [], // 包含文件列表
        "exclude": [], // 不包含文件列表
        "includePattern": ".+\\.js(doc)?$", // 正则方式
        "excludePattern": "(^|\\/|\\\\)_"
    },
    "plugins": [], // 启用插件列表,可在 JSDoc 目录下找到所有的插件
    "templates": {
        "cleverLinks": false,
        "monospaceLinks": false
    },
    "opts": { // 命令行操作参数配置,详细内容请查看 http://usejsdoc.org/about-commandline.html
        "template": "templates/default",  // same as -t templates/default
        "encoding": "utf8",               // same as -e utf8
        "destination": "./out/",          // same as -d ./out/
        "recurse": true,                  // same as -r
        "tutorials": "path/to/tutorials", // same as -u path/to/tutorials, default "" (no tutorials)
        "query": "value",                 // same as -q value, default "" (no query)
        "private": true,                  // same as -p
        "lenient": true,                  // same as -l
        // these can also be included, though you probably wouldn't bother
        // putting these in conf.json rather than the command line as they cause
        // JSDoc not to produce documentation. 
        "version": true,                  // same as --version or -v
        "explain": true,                  // same as -X
        "test": true,                     // same as -T
        "help": true,                     // same as --help or -h
        "verbose": true,                  // same as --verbose, only relevant to tests.
        "match": "value",                 // same as --match value, only relevant to tests.
        "nocolor": true                   // same as --nocolor, only relevant to tests
    }
}