Merge pull request #6 from brantyoung/master

Pull from https://brantyoung/zh-google-styleguide
This commit is contained in:
Brant.Y 2014-05-07 11:12:03 +08:00
commit 0725927eec
14 changed files with 3369 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
背景
================================
本文档定义了HTML/CSS的排版以及风格的规则。旨在促进合作编程、提高代码质量并且支持基本的架构。它适用于原生的HTML和CSS文件包括GSS文件。只要保证代码的整体质量就可以很容易地使用工具进行混淆、压缩和合并。

View File

@ -0,0 +1,176 @@
CSS格式化规则
===============
声明顺序
---------
按字母顺序排列声明。
css文件书写按字母顺序排列的方式容易记忆和维护以达到一致的代码。
在排序时忽略浏览器特定的前缀。但是特定CSS属性的多个浏览器前缀应按字母顺序排列如-moz书写在-webkit前面
.. code-block:: css
background: fuchsia;
border: 1px solid;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
color: black;
text-align: center;
text-indent: 2em;
块内容的缩进
--------------
缩进块内容。
将包括嵌套及声明的 `块内容 <http://www.w3.org/TR/CSS21/syndata.html#block>`_ 进行缩进,以体现层次并提高可读性。
.. code-block:: css
@media screen, projection {
html {
background: #fff;
color: #444;
}
}
声明结束
----------
每个属性后使用分号结束。
以分号结束每个属性,提高一致性和可扩展性。
.. code-block:: css
/* 不推荐 */
.test {
display: block;
height: 100px
}
/* 推荐 */
.test {
display: block;
height: 100px;
}
CSS属性名结束
---------------
属性名称的冒号后有一个空格。
为保证一致性,在属性名与属性值之间添加一个空格(但是属性名和冒号间没有空格)。
.. code-block:: css
/* 不推荐 */
h3 {
font-weight:bold;
}
/* 推荐 */
h3 {
font-weight: bold;
}
声明块间隔
--------------
在选择器和后面的声明块之间使用一个空格。
最后一个选择器与表示 `声名块 <http://www.w3.org/TR/CSS21/syndata.html#rule-sets>`_ 开始的左大花括号在同行,中间有一个字符空格。
表示开始的左大花括号和选择器在同行。
.. code-block:: css
/* 不推荐:缺少空间 */
#video{
margin-top: 1em;
}
/* 不推荐:不必要的换行符 */
#video
{
margin-top: 1em;
}
/* 推荐 */
#video {
margin-top: 1em;
}
选择器及声明分离
-------------------
每个选择器和声明独立成行。
总是让每个选择器和声明单独成行。
.. code-block:: css
/* 不推荐 */
a:focus, a:active {
position: relative; top: 1px;
}
/* 推荐 */
h1,
h2,
h3 {
font-weight: normal;
line-height: 1.2;
}
CSS代码块分离
-----------------
使用新空行分离规则。
始终把一个空行(两个换行符)放在代码块规则之间。
.. code-block:: css
html {
background: #fff;
}
body {
margin: auto;
width: 50%;
}
CSS引号
----------
属性选择器和属性值中使用单引号。
在属性选择器及属性值中使用单引号('')而不是双引号("")。在 ``url`` 中不要使用引号。
特例:如果你确实需要定义 ``@charset`` ,由于 `不允许使用单引号 <http://www.w3.org/TR/CSS21/syndata.html#charset>`_ ,故请使用双引号。
.. code-block:: css
/* 不推荐 */
@import url("//www.google.com/css/maia.css");
html {
font-family: "open sans", arial, sans-serif;
}
/* 推荐 */
@import url(//www.google.com/css/maia.css);
html {
font-family: 'open sans', arial, sans-serif;
}

View File

@ -0,0 +1,23 @@
CSS元规则
===========
分段规则
----------
组的分段由一段注释完成(可选)。
尽可能地用注释来将css分段段与段之间采用新行。
.. code-block:: css
/* Header */
#adw-header {}
/* Footer */
#adw-footer {}
/* Gallery */
.adw-gallery {}

View File

@ -0,0 +1,190 @@
css样式规则
==================
CSS有效性
----------
尽可能使用有效的CSS。
使用有效的CSS代码除非在处理css验证器bug或者是专有的语法时。
使用诸如 `W3C CSS validator <http://jigsaw.w3.org/css-validator/>`_ 等工具验证测试。
使用有效的CSS代码是一个可衡量CSS代码质量的指标可帮你找出不起作用可被删除的CSS代码从而确保CSS的合理使用。
id与class的命名
-----------------
使用有意义的或者通用的id和class名称
用能反映出元素目的或者通用的id、class名称代替那些很表象的、难懂的名称。
如果名称需要是易懂的,或不容易被修改,应该首选特定的或者能反映出元素目的的名称。
通用的名称适用于非特殊元素或与兄弟元素无区别的元素。他们常被称为“辅助元素”。
使用功能性或者通用的名称,可减少不必要的文档或者模板变化。
.. code-block:: css
/* 不推荐:无意义 */
#yee-1901 {}
/* 不推荐:表象 */
.button-green {}
.clear {}
/* 推荐:具体的 */
#gallery {}
#login {}
.video {}
/* 推荐:通用的 */
.aux {}
.alt {}
id与class的命名规范
-----------------------
ID和class命名要尽可能简短但必要的话就别怕长。
尽可能简洁地传达id或者class名称的含义。
使用简洁的id或者class名称有助于提高可读性和代码效率。
.. code-block:: css
/* 不推荐 */
#navigation {}
.atr {}
/* 推荐 */
#nav {}
.author {}
选择器的类型
--------------
应当避免在id和class前添加类型选择器。
除了必要情况下例如辅助的类不要将元素与id或class名称结合做为选择器。
避免不必要的祖先选择器也是出于 `性能原因 <http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/>`_ 的考虑。
.. code-block:: css
/* 不推荐 */
ul#example {}
div.error {}
/* 推荐 */
#example {}
.error {}
简写属性
------------
尽可能使用简写的属性书写方式。
CSS提供了多种属性 `简写 <http://www.w3.org/TR/CSS21/about.html#shorthand>`_ 的方式(如 ``font`` ),即使只显式设置一个值,也应该尽可能地使用。
使用简写属性有助于提高代码效率及可读性。
.. code-block:: css
/* 不推荐 */
border-top-style: none;
font-family: palatino, georgia, serif;
font-size: 100%;
line-height: 1.6;
padding-bottom: 2em;
padding-left: 1em;
padding-right: 1em;
padding-top: 0;
/* 推荐 */
border-top: 0;
font: 100%/1.6 palatino, georgia, serif;
padding: 0 1em 2em;
0与单位
----------
省略“0”后的单位。
除非必需否则0后不要加单位。
.. code-block:: css
margin: 0;
padding: 0;
前导0
-----------
省略前导“0”值。
在-1至1之间的值无需保留整数位的0。
.. code-block:: css
font-size: .8em;
十六进制表示法
----------------
在可能的情况下使用3个字符的十六进制表示法。
对于可用3字符十六进制表示的颜色值按此规则书写更短、更简洁。
.. code-block:: css
/* 不推荐 */
color: #eebbcc;
/* 推荐 */
color: #ebc;
前缀选择器
------------
加特定应用前缀(可选)
大型项目中以及嵌入在其它项目或外部网站上的代码需要给id和class添加前缀命名空间。使用短的、独特的标识符并在其后跟一个破折号。
使用命名空间有助于防止命名冲突,可以让维护变得简单,例如在搜索和替换操作时。
.. code-block:: css
.adw-help {} /* AdWords */
#maia-note {} /* Maia */
id与class名称分隔符
---------------------
用连字符分隔ID和类名中的单词。
选择器中的词语和缩写中不要使用除了连字符以外的任何字符(包括空字符),以提高可理解性和可读性。
.. code-block:: css
/* 不推荐: 单词未分开 */
.demoimage {}
/* 不推荐:使用下划线而不是连字符 */
.error_status {}
/* 推荐 */
#video-id {}
.ads-sample {}
Hacks
------------
请先尝试其他的方法避免用户代理检测以及CSS的“hacks”。
进行用户代理检测或使用特殊的CSS选择器及hacks看起来是处理样式差异的捷径。但为了实现和保持高效性以及代码的可维护性这两种方案应该放到最后考虑。换句话说用户代理检测和使用hacks会增大项目推进的阻力所以从项目的长远利益考虑应尽力避免。一旦允许并无顾忌地使用用户代理检测和hacks便很容易滥用最终一发而不可收。

View File

@ -0,0 +1,60 @@
总体排版规则
==============
缩进
---------
每次缩进使用两个空格。
不使用TAB键或者混合使用TAB键和空格进行缩进。
.. code-block:: html
<ul>
<li>Fantastic
<li>Great
</ul>
.. code-block:: css
.example {
color: blue;
}
大小写
----------
只使用小写字母。
所有的代码都使用小写字母适用于HTML元素、属性、属性值除了text/CDATA、CSS选择器、属性名以及属性值字符串除外
.. code-block:: html
<!-- 不推荐 -->
<A HREF="/">Home</A>
<!-- 推荐 -->
<img src="google.png" alt="Google">
.. code-block:: css
/* 不推荐 */
color: #E5E5E5;
/* 推荐 */
color: #e5e5e5;
尾部的空格
------------
删除尾部的空格。
尾部的空格是多余的,不删除则形成无意义的文件差异。
.. code-block:: html
<!-- 不推荐 -->
<p>What?_
<!-- 推荐 -->
<p>Yes please.

View File

@ -0,0 +1,44 @@
整体的元数据规则
===================
编码
---------
使用UTF-8无BOM编码。
让你的编辑器使用无字节顺序标记的UTF-8编码。
在HTML模板和文档中使用 ``<meta charset=”utf-8”>`` 指定编码。不需要为样式表指定编码它默认是UTF-8。
(想了解更多关于应该何时并如何指定编码,请查看 `Handling character encodings in HTML and CSS <http://www.w3.org/International/tutorials/tutorial-char-enc/>`_
注释
--------
在需要时尽可能去解释你的代码。
用注释去解释你的代码,包括它的应用范围、用途、此方案的选择理由等。
这一条是可选的没必要为每个文件写上详细的注释会增重HTML/CSS的代码主要取决于项目的复杂度。
处理内容
----------
用TODO标记待办事宜和处理内容。
只用TODO来标记待办事宜不要使用其他格式例如@@。
在括号里添加联系方式姓名或邮箱格式为TODO联系方式
在冒号后面添加处理内容格式为TODO处理内容。
.. code-block:: html
{# TODO(john.doe): 重新处理水平居中 #}
<center>Test</center>
<!-- TODO: 移除可选的标签 -->
<ul>
<li>Apples</li>
<li>Oranges</li>
</ul>

View File

@ -0,0 +1,31 @@
整体样式规则
================
协议
---------------
嵌入式资源省略协议头。
省略图片、媒体文件、样式表以及脚本的URL协议头部分http:、https:),不使用这两个协议的文件则不省略。
省略协议头即让URL变成相对地址可以避免协议混合及小文件重复下载。
.. code-block:: html
<!-- 不推荐 -->
<script src="http://www.google.com/js/gweb/analytics/autotrack.js"></script>
<!-- 推荐 -->
<script src="//www.google.com/js/gweb/analytics/autotrack.js"></script>
.. code-block:: css
/* 不推荐 */
.example {
background: url(http://www.google.com/images/example);
}
/* 推荐 */
.example {
background: url(//www.google.com/images/example);
}

View File

@ -0,0 +1,51 @@
HTML格式规则
==============
常规格式化
------------
对每个块、列表、表格元素都另起一行,每个子元素都缩进。
每个块元素、列表元素或表格元素另起一行而不必考虑元素的样式因CSS可以改变元素的 ``display`` 属性)。
同样的,如果他们是块、列表或者表格元素的子元素,则将之缩进。
(如果你遇到列表项之间有空白的问题,可以把所有 ``li`` 元素放到一行。Linter鼓励抛出警告而不是错误。
.. code-block:: html
<blockquote>
<p><em>Space</em>, the final frontier.</p>
</blockquote>
<ul>
<li>Moe
<li>Larry
<li>Curly
</ul>
<table>
<thead>
<tr>
<th scope="col">Income
<th scope="col">Taxes
<tbody>
<tr>
<td>$ 5.00
<td>$ 4.50
</table>
HTML引号
-----------
当引用属性值时,使用双引号。
使用双引号而不是单引号来包裹属性值。
.. code-block:: html
<!-- 不推荐 -->
<a class='maia-button maia-button-secondary'>Sign in</a>
<!-- 推荐 -->
<a class="maia-button maia-button-secondary">Sign in</a>

View File

@ -0,0 +1,174 @@
HTML样式规则
==============
文档类型
---------
使用HTML5。
HTML5HTML语法是所有HTML文档的首选 ``<!DOCTYPE html>``
推荐使用HTML即text/html。不要使用XHTML。XHTML`application/xhtml+xml <http://hixie.ch/advocacy/xhtml>`_缺乏浏览器和基础结构的支持并且优化的空间比HTML小。
虽然HTML闭合标签没有问题但是不要自闭合空标签。即写 ``<br>`` 而不是 ``<br />``
HTML合法性
------------
在可能的情况下使用合法的HTML。
使用合法的HTML代码除非由于文件大小导致的不可达到的性能目标而不能使用。
利用已用工具对合法性进行测试,例如 `W3C HTML validator <http://validator.w3.org/nu/>`_
使用合法的HTML是一个可度量的基准质量属性该属性有助于了解技术需求和约束从而确保合理的HTML使用。
.. code-block:: html
<!-- 不推荐 -->
<title>Test</title>
<article>This is only a test.
<!-- 推荐 -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test</title>
<article>This is only a test.</article>
语义化
--------
根据HTML的目的使用它。
根据元素(有时被错误的叫做“标签”)被创造的用途使用他们。比如,对标题使用标题元素,对段落使用 ``p`` 元素,对锚点使用 ``a`` 元素等。
语义化的使用HTML对于可访问性、复用性和代码的高效性等因素非常重要。
.. code-block:: html
<!-- 不推荐 -->
<div onclick="goToRecommendations();">All recommendations</div>
<!-- 推荐 -->
<a href="recommendations/">All recommendations</a>
多媒体降级
------------
为多媒体提供替代内容。
对于图片、视频、通过 ``canvas`` 实现的动画等多媒体来说,确保提供可访问的替代内容。对于图片,可提供有意义的替代文本( ``alt`` );对于视频和音频,如有条件可提供对白和字幕。
提供替代内容对辅助功能很重要:没有 ``alt`` ,一位盲人用户很难知道一张图片的内容,其他用户可能不能了解视频和音频的内容。
(对于 ``alt`` 属性会引起冗余的图片和你不打算添加CSS的纯粹装饰性的图片不用添加替代文本写成 ``alt=""`` 即可。)
.. code-block:: html
<!-- 不推荐 -->
<img src="spreadsheet.png">
<!-- 推荐 -->
<img src="spreadsheet.png" alt="Spreadsheet screenshot.">
关注点分离
-----------
将结构、表现、行为分离。
严格保持结构(标识),表现(样式),行为(脚本)分离,尽量使三者之间的相互影响最小。
就是说确保文档和模板只包含HTML并且HTML只用来表现结构。把任何表现性的东西都移到样式表任何行为性的东西都移到脚本中。
此外,尽可能少的从文档和模板中引用样式表和脚本来减少三者的相互影响。
结构、表现、行为分离对维护非常重要。更改HTML文档和模板总是比更新样式表和脚本成本更高。
.. code-block:: html
<!-- 不推荐 -->
<!DOCTYPE html>
<title>HTML sucks</title>
<link rel="stylesheet" href="base.css" media="screen">
<link rel="stylesheet" href="grid.css" media="screen">
<link rel="stylesheet" href="print.css" media="print">
<h1 style="font-size: 1em;">HTML sucks</h1>
<p>Ive read about this on a few sites but now Im sure:
<u>HTML is stupid!!1</u>
<center>I cant believe theres no way to control the styling of
my website without doing everything all over again!</center>
<!-- 推荐 -->
<!DOCTYPE html>
<title>My first CSS-only redesign</title>
<link rel="stylesheet" href="default.css">
<h1>My first CSS-only redesign</h1>
<p>Ive read about this on a few sites but today Im actually
doing it: separating concerns and avoiding anything in the HTML of
my website that is presentational.
<p>Its awesome!
实体引用
-----------
不要使用实体引用。
假设文件、编辑器和团队之间使用相同的编码UTF-8则没有必要使用例如 ``&mdash;````&rdquo;````&#x263a;`` 这样的实体引用。
唯一的例外适用于HTML中具有特殊意义的字符比如<和&),和控制或者隐藏的字符(比如不换行空格)。
.. code-block:: html
<!-- 不推荐 -->
The currency symbol for the Euro is &ldquo;&eur;&rdquo;.
<!-- 推荐 -->
The currency symbol for the Euro is "€".
可选的标签
------------
省略可选的标签(可选)。
为了优化文件大小和可扫描,考虑省略可选标签。 `HTML5规范 <http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#syntax-tag-omission>`_ 定义了哪些标签可以被省略。
这种方法可能要求一段宽限期去建立一个更加广泛的准则因为它和Web开发人员通常所了解的有着显著不同。考虑到一致性和简单性最好省略所有可选标签。
.. code-block:: html
<!-- 不推荐 -->
<!DOCTYPE html>
<html>
<head>
<title>Spending money, spending bytes</title>
</head>
<body>
<p>Sic.</p>
</body>
</html>
<!-- 推荐 -->
<!DOCTYPE html>
<title>Saving money, saving bytes</title>
<p>Qed.
type属性
---------
为样式表和脚本省略 ``type`` 属性。
引用样式表除非不是使用CSS和脚本除非不是使用JavaScript不要使用type属性。
HTML5将 `text/css <http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#attr-style-type>`_`text/javascript <http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-type>`_ 设置为默认值在这种情况下指定type属性并不必要。甚至同样兼容老版本的浏览器。
.. code-block:: html
<!-- 不推荐 -->
<link rel="stylesheet" href="//www.google.com/css/maia.css" type="text/css">
<!-- 推荐 -->
<link rel="stylesheet" href="//www.google.com/css/maia.css">
<!-- 不推荐 -->
<script src="//www.google.com/js/gweb/analytics/autotrack.js" type="text/javascript"></script>
<!-- 推荐 -->
<script src="//www.google.com/js/gweb/analytics/autotrack.js"></script>

View File

@ -0,0 +1,8 @@
赠言
========
请与周围保持一致。
如果你正在编辑代码,花几分钟时间看看上下文代码的格式,确定他们的编码风格。如果在上下文代码中,算术运算符前后有空格,或注释前后添加了“#”,你也应该这样做。
编写这个风格指导的目标是让人们可以专注于“我们在讨论什么”而不是“我们该怎么描述”。我们提供了一些通用的编码规范,大家就可以基于这些规范而继续,但特定情况下的规范也同样重要。如果你在一个文件中添加的代码看上去跟其他代码明显不同,你就把阅读此文件的人的节奏打乱了。避免这种情况出现。

View File

@ -0,0 +1,4 @@
背景
==============
在Google的开源项目中JavaScript是最主要的客户端脚本语言。本指南是使用JavaScript时建议和不建议做法的清单。

View File

@ -0,0 +1,538 @@
Javascript语言规则
==========
var关键字
----------------
总是用 ``var`` 关键字定义变量。
描述
~~~~~~
如果不显式使用 ``var`` 关键字定义变量变量会进入到全局上下文中可能会和已有的变量发生冲突。另外如果不使用var声明很难说变量存在的作用域是哪个可能在局部作用域里也可能在document或者window上。所以要一直使用 ``var`` 关键字定义变量。
常量
----------------
* 使用字母全部大写(如 ``NAMES_LIKE_THIS`` )的方式命名
* 可以使用 ``@const`` 来标记一个常量 *指针* (指向变量或属性,自身不可变)
* 由于IE的兼容问题不要使用 `const关键字 <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FStatements%2Fconst>`_
描述
~~~~~~
常量值
########
如果一个值是恒定的,它命名中的字母要全部大写(如 ``CONSTANT_VALUE_CASE`` )。字母全部大写意味着这个值不可以被改写。
原始类型( ``number````string````boolean`` )是常量值。
对象的表现会更主观一些,当它们没有暴露出变化的时候,应该认为它们是常量。但是这个不是由编译器决定的。
常量指针(变量和属性)
########################
``@const`` 注释的变量和属性意味着它是不能更改的。使用const关键字可以保证在编译的时候保持一致。使用 `const <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FStatements%2Fconst>`_ 效果相同但是由于IE的兼容问题我们不使用const关键字。
另外,不应该修改用 ``@const`` 注释的方法。
例子
########
注意, ``@const`` 不一定是常量值,但命名类似 ``CONSTANT_VALUE_CASE``*一定* 是常量指针。
::
/**
* 以毫秒为单位的超时时长
* @type {number}
*/
goog.example.TIMEOUT_IN_MILLISECONDS = 60;
1分钟60秒永远也不会改变这是个常量。全部大写的命名意味其为常量值所以它不能被重写。
开源的编译器允许这个符号被重写,这是因为 *没有* ``@const`` 标记。
::
/**
* Map of URL to response string.
* @const
*/
MyClass.fetchedUrlCache_ = new goog.structs.Map();
在这个例子中,指针没有变过,但是值却是可以变化的,所以这里用了驼峰式的命名,而不是全部大写的命名。
分号
---------
一定要使用分号。
依靠语句间隐式的分割,可能会造成细微的调试的问题,千万不要这样做。
很多时候不写分号是很危险的:
::
// 1.
MyClass.prototype.myMethod = function() {
return 42;
} // 这里没有分号.
(function() {
// 一些局部作用域中的初始化代码
})();
var x = {
'i': 1,
'j': 2
} //没有分号.
// 2. 试着在IE和firefox下做一样的事情.
//没人会这样写代码,别管他.
[normalVersion, ffVersion][isIE]();
var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] //这里没有分号
// 3. 条件语句
-1 == resultOfOperation() || die();
发生了什么?
~~~~~~~~~~~~~
1. js错误。返回42的函数运行了因为后面有一对括号而且传入的参数是一个方法然后返回的42被调用导致出错了。
2. 你可能会得到一个“no sush property in undefined”的错误因为在执行的时候解释器将会尝试执行 ``x[normalVersion, ffVersion][isIE]()`` 这个方法。
3. ``die`` 这个方法只有在 ``resultOfOperation()````NaN`` 的时候执行,并且 ``THINGS_TO_EAT`` 将会被赋值为 ``die()`` 的结果。
为什么?
~~~~~~~~~~~~
js语句要求以分号结尾除非能够正确地推断分号的位置。在这个例子当中函数声明、对象和数组字面量被写在了一个语句当中。右括号")"、"}"、"]")不足以证明这条语句已经结束了,如果下一个字符是运算符或者"("、"{"、"["js将不会结束语句。
这个错误让人震惊,所以一定要确保用分号结束语句。
澄清:分号和函数
~~~~~~~~~~~~~~
函数表达式后面要分号结束,但是函数声明就不需要。例如:
::
var foo = function() {
return true;
}; // 这里要分号
function foo() {
return true;
} // 这里不用分号
嵌套函数
-----------------
可以使用。
嵌套函数非常有用,比如在创建持续任务或者隐藏工具方法的时候。可以放心的使用。
块内函数声明
---------------------------
不要使用块内函数声明。
不要这样做:
::
if (x) {
function foo() {}
}
虽然大多数脚本引擎支持功能区块内声明但ECMAScript并未认可`ECMA-262 <http://www.ecma-international.org/publications/standards/Ecma-262.htm>`_ 第13条和第14。若与他人的及EcmaScript所建议的不一致即可视为不好的实现方式。ECMAScript只允许函数声明语句列表, 在根语句列表脚本或者函数。相反,使用一个变量初始化函数表达式在块内定义一个函数块:
::
if (x) {
var foo = function() {}
}
异常
-------
可以抛出异常。
如果你做一些比较复杂的项目你基本上无法避免异常,比如使用一个应用程序开发框架。可以大胆试一试。
自定义异常
----------
可以自定义异常。
如果没有自定义异常返回的错误信息来自一个有返回值的函数是难处理的是不雅的。坏的解决方案包括传递引用的类型来保存错误信息或总是返回有一个潜在的错误成员的对象。这些基本上为原始的异常处理hack。在适当的时候使用自定义的异常。
标准功能
----------
总是优先于非标准功能。
为了最大的可移植性和兼容性,总是使用标准功能而不是非标准功能(例如,采用 `string.charAt(3)` 而非 `string[3]` 用DOM的功能访问元素而不是使用特定于一个具体应用的简写
原始类型的包装对象
------------------
没有理由使用原始类型的包装对象,更何况他们是危险的:
::
var x = new Boolean(false);
if (x) {
alert('hi'); //显示“hi”。
}
不要这样做!
然而类型转换是可以的。
::
var x = Boolean(0);
if (x) {
alert('hi'); //永远都不显示。
}
typeof Boolean(0) == 'boolean';
typeof new Boolean(0) == 'object';
这是非常有用的进行数字、字符串和布尔值转换的方式。
多重的原型继承
-------------------
不可取。
多重原型继承是Javascript实现继承的方式。如果你有一个以用户定义的class B作为原型的用户自定义class D则得到多重原型继承。这样的继承出现容易但难以正确创造
出于这个原因,最好是使用 `Closure库 <https://developers.google.com/closure/library/?csw=1>`_ 中的 ``goog.inherits()`` 或类似的东西。
::
function D() {
goog.base(this)
}
goog.inherits( D, B );
D.prototype.method =function() {
...
};
方法和属性定义
-------------------------
``/**构造函数*/ function SomeConstructor() { this.someProperty = 1; } Foo.prototype.someMethod = function() { ... };``
虽然有多种使用“new”关键词来创建对象方法和属性的途径首选的创建方法的途径是
::
Foo.prototype.bar = function() {
/* ... */
};
其他特性的首选创建方式是在构造函数中初始化字段:
::
/** @constructor */
function Foo() {
this.bar = value;
}
为什么?
~~~~~~~~~~
当前的JavaScript引擎优化基于一个对象的“形状” `给对象添加一个属性(包括覆盖原型设置的值)改变了形式,会降低性能 <https://developers.google.com/v8/design#prop_access>`_
删除
----------
请使用 ``this.foo = null``
::
o.prototype.dispose = function() {
this.property_ = null;
};
而不是:
::
Foo.prototype.dispose = function() {
delete his.property_;
};
在现代的JavaScript引擎中改变一个对象属性的数量比重新分配值慢得多。应该避免删除关键字除非有必要从一个对象的迭代的关键字列表删除一个属性或改变 ``if (key in obj)`` 结果。
闭包
-------------
可以使用,但是要小心。
创建闭包可能是JS最有用的和经常被忽视的功能。在 `这里 <http://jibbering.com/faq/notes/closures/>`_ 很好地描述说明了闭包的工作。
要记住的一件事情一个闭包的指针指向包含它的范围。因此附加一个闭包的DOM元素可以创建一个循环引用所以内存会泄漏。例如下面的代码
::
function foo(element, a, b) {
element.onclick = function() { /* 使用 a 和 b */ };
}
闭包能保持元素a和b的引用即使它从未使用。因为元素还保持对闭包的一个引用我们有一个循环引用不会被垃圾收集清理。在这些情况下代码的结构可以如下
::
function foo(element, a, b) {
element.onclick = bar(a, b);
}
function bar(a, b) {
return function() { /* 使用 a 和 b */ }
}
eval()函数
------------------------
只用于反序列化如评估RPC响应
若用于 ``eval()`` 的字符串含有用户输入,则 ``eval()`` 会造成混乱的语义,使用它有风险。通常有一个更好
更清晰、更安全的方式来编写你的代码所以一般是不会允许其使用的。然而eval相对比非eval使反序列化更容易因此它的使用是可以接受的例如评估RPC响应
反序列化是将一系列字节存到内存中的数据结构转化过程。例如,你可能会写的对象是:
::
users = [
{
name: 'Eric',
id: 37824,
email: 'jellyvore@myway.com'
},
{
name: 'xtof',
id: 31337,
email: 'b4d455h4x0r@google.com'
},
...
];
将这些数据读入内存跟得出文件的字符串表示形式一样容易。
同样, ``eval()`` 函数可以简化解码RPC的返回值。例如您可以使用 ``XMLHttpRequest`` 生成RPC在响应时服务器返回JavaScript
::
var userOnline = false;
var user = 'nusrat';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://chat.google.com/isUserOnline?user=' + user, false);
xmlhttp.send('');
// 服务器返回:
// userOnline = true;
if (xmlhttp.status == 200) {
eval(xmlhttp.responseText);
}
// userOnline 现在为 true
with() {}
----------------------
不建议使用。
使用 ``with`` 会影响程序的语义。因为 ``with`` 的目标对象可能会含有和局部变量冲突的属性,使你程序的语义发生很大的变化。例如,这是做什么用?
::
with (foo) {
var x = 3;
return x;
}
答案:什么都有可能。局部变量 ``x`` 可能会被 ``foo`` 的一个属性覆盖它甚至可能有setter方法在此情况下将其赋值为3可能会执行很多其他代码。不要使用 ``with``
this
-------------------
只在构造函数对象、方法,和创建闭包的时候使用。
``this`` 的语义可能会非常诡异。有时它指向全局对象(很多时候)、调用者的作用域链(在 ``eval``、DOM树的一个节点当使用HTML属性来做为事件句柄时、新创建的对象在一个构造函数中、或者其他的对象如果函数被 ``call()````apply()`` 方式调用)。
正因为 ``this`` 很容易被弄错,故将其使用限制在以下必须的地方:
* 在构造函数中
* 在对象的方法中(包括闭包的创建)
for-in 循环
------------------
只使用在对象、映射、哈希的键值迭代中。
``for-in`` 循环经常被不正确的用在元素数组的循环中。由于并不是从 ``0````length-1`` 进行循环,而是遍历对象中和它原型链上的所有的键,所以很容易出错。这里有一些失败的例子:
::
function printArray(arr) {
for (var key in arr) {
print(arr[key]);
}
}
printArray([0,1,2,3]); //这样可以
var a = new Array(10);
printArray(a); //这样不行
a = document.getElementsByTagName('*');
printArray(a); //这样不行
a = [0,1,2,3];
a.buhu = 'wine';
printArray(a); //这样不行
a = new Array;
a[3] = 3;
printArray(a); //这样不行
在数组循环时常用的一般方式:
::
function printArray(arr) {
var l = arr.length;
for (var i = 0; i < l; i++) {
print(arr[i]);
}
}
关联数组
-----------------------
不要将映射,哈希,关联数组当作一般数组来使用。
不允许使用关联数组……确切的说在数组,你不可以使用非数字的索引。如果你需要一个映射或者哈希,在这种情况下你应该使用对象来代替数组,因为在功能上你真正需要的是对象的特性而不是数组的。
数组仅仅是用来拓展对象的像在JS中你曾经使用过的 ``Date````RegExp````String`` 对象一样的)。
多行的字符串字面量
------------------------------------
不要使用。
不要这样做:
::
var myString = 'A rather long string of English text, an error message \
actually that just keeps going and going -- an error \
message to make the Energizer bunny blush (right through \
those Schwarzenegger shades)! Where was I? Oh yes, \
you\'ve got an error and all the extraneous whitespace is \
just gravy. Have a nice day.';
在编译时每一行头部的空白符不会被安全地去除掉斜线后的空格也会导致棘手的问题虽然大部分脚本引擎都会支持但是它不是ECMAScript规范的一部分。
使用字符串连接来代替:
::
var myString = 'A rather long string of English text, an error message ' +
'actually that just keeps going and going -- an error ' +
'message to make the Energizer bunny blush (right through ' +
'those Schwarzenegger shades)! Where was I? Oh yes, ' +
'you\'ve got an error and all the extraneous whitespace is ' +
'just gravy. Have a nice day.';
数组和对象字面量
----------------------------------
建议使用。
使用数组和对象字面量来代替数组和对象构造函数。
数组构造函数容易在参数上出错。
::
// 长度为3
var a1 = new Array(x1, x2, x3);
// 长度为 2
var a2 = new Array(x1, x2);
// If x1 is a number and it is a natural number the length will be x1.
// If x1 is a number but not a natural number this will throw an exception.
// Otherwise the array will have one element with x1 as its value.
var a3 = new Array(x1);
// 长度为0
var a4 = new Array();
由此如果有人将代码从2个参数变成了一个参数那么这个数组就会有一个错误的长度。
为了避免这种怪异的情况,永远使用可读性更好的数组字面量。
::
var a = [x1, x2, x3];
var a2 = [x1, x2];
var a3 = [x1];
var a4 = [];
对象构造函数虽然没有相同的问题,但是对于可读性和一致性,还是应该使用对象字面量。
::
var o = new Object();
var o2 = new Object();
o2.a = 0;
o2.b = 1;
o2.c = 2;
o2['strange key'] = 3;
应该写成:
::
var o = {};
var o2 = {
a: 0,
b: 1,
c: 2,
'strange key': 3
};
修改内置对象原型
--------------------------------
不建议。
强烈禁止修改如 ``Object.prototype````Array.prototype`` 等对象的原型。修改其他内置原型如 ``Function.prototype`` 危险性较小,但在生产环境中还是会引发一些难以调试的问题,也应当避免。
Internet Explorer中的条件注释
----------------------------------------------------------
不要使用。
不要这样做:
::
var f = function () {
/*@cc_on if (@_jscript) { return 2* @*/ 3; /*@ } @*/
};
条件注释会在运行时改变JavaScript语法树阻碍自动化工具。

File diff suppressed because it is too large Load Diff