既然要写JS,必须要遵循一定的编程规范吧。以下是来自Google的JS语言规范,直接翻译过来的(可参考英文原版)。
1,变量:大部分情况下请使用var声明
如果不显示使用var,这个变量就会被附着在全局上下文中,可能引起重名的冲突。而且,如果不使用var声明,也 很难分辨这个变量的作用域(如:可能附着在Document或Window对象上,也可能附着在局部变量上)。所以,大部 分情况下使用var来声明变量。
当然,如果申请一个只属于某一个“类”的变量,则不要使用var。如jQuery(版本为1.6.4)中为jQuery的第41 行,要为jQuery对象增加属性,所以不能使用var来声明。
2,常量:使用NAME_LIKE_THIS的命名方法,适当使用@const,不要使用const关键词。
对于简单的“非引用”类型,这种命名方法足矣。如:
/**
* The number of seconds in a minute.
* @type {number}
*/
goog.example.SECONDS_IN_A_MINUTE = 60;
对于“引用”类型,使用@const注解。如:
/**
* The number of seconds in each of the given units.
* @type {Object.<number>}
* @const
*/
goog.example.SECONDS_TABLE = {
minute: 60,
hour: 60 * 60
day: 60 * 60 * 24
}
这样可以保证编译器保证常量的意义。
至于const关键字,由于IE不支持,所以不要使用。
3,分号:使用之。
不显式使用分号,有可能导致难以察觉的问题。特别是如下几处:
//1.
MyClass.prototype.myMethod = function(){
return 42;
} // 这里没有分号
(function(){
//初始化一些变量,作用域为该匿名函数
})();
var x = {
'i':1,
'j':2
} //这里没有分号
//2.
[normalVersion,ffVersion][isIE]();
var THINGS_TO_EAT = [apples,oysters,sprayOnCheese] //没有分号
//3.
-1 == resultOfOperation() || die();
发生什么呢?
第一处:JS错误-首先,返回24的函数会执行,因为后面有一个圆括号,而且参数是一个函数;然后返回值42 被调用,出错。
第二处:执行的时候你非常可能得到一个“no such property in undefined”的错误,因为实际上是在执行 x[ffVersion][isIE]()这个函数。
第三处:函数die只有在resultOfOperation()为NaN,THINGS_TO_EAT会被赋值成die()的返回值。
为什么呢?
JS的语法要求一个语句要以分号结尾,除非能安全的推断出分号的位置。在上述例子中,函数声明,对象声明, 数组等被用在一个语句中。类似如“}”,“]”的符号不足以证明语句的结束。如果下一个字符是运算符或者"{","[",则 JS会认为语句没有结束。
这写错误令人诧异,所以确保赋值语句以分号结尾。
4,嵌套函数:可以使用
嵌套函数非常有用,比如在创建持续任务或者隐藏工具函数的时候。不用担心,使用之。
5,在语言块中声明函数:不要使用!
不要写如下代码:
if(x){
function ff(){}
}
尽管大多数脚本引擎支持这种函数声明的方式,但是这并不是ECMAScript标准里面的。ECMAScript只支持在 根语句声明函数。如果需要,可以使用变量来保存这个函数。如下:
if(x){
var ff = function(){}
}
6,异常:可以使用
如果不是从0开始写,那么基本上避免不了使用异常,如使用程序开发框架的时候。
7,自定义异常:可以使用
没有自定义异常,那么一个函数既可以返回正常值,又可以返回一个错误信息,这令人费解。不大优雅的解决方 法包括返回执行错误信息的引用类型和返回包含潜在错误的对象。这些可以说是比较古老的异常处理方法。所以,在 合适的情况下可以使用自定义异常。
8,标准特性:使用标准特性而不是使用非标准的
为了最大化的实现可移植和兼容。比如使用string.charAt(4),而不是使用string[4];访问元素要使用DOM函 数,而不是使用某个专属于一个工程的简写。
9,为原始类型包装:不要使用!
没有必要为原始类型包装,而且包装还很容易出错,如下:
var x = new Boolean(false);
if(x){
alert('hi');//会执行
}
不要这样做!
然而,类型转换还是可以的。
var x = Boolean(0);
if(x){
alert('hi');//不执行
}
typeof Boolean(0) == 'boolean';
typeof new Boolean(0) == 'object';
这个特点在将对象转型成number,string,boolean的时候特别有用。
10,多级原型层次:不建议使用
多级原型层次可以用来实现继承。多级原型很难维护。
(这个本人保留意见)
11,方法定义:Foo.prototype.bar = function(){};
尽管有好几种方式将方法和属性绑定到一个类,最好的还是这种。
12,闭包:可以使用,但是要小心!
闭包也许是JS最有用的特点,或许也是最被滥用的特性。
但是,要记住,闭包持有对它的关闭范围的引用。如果将一个闭包赋值给DOM元素,则可能导致循环引用,从 而引起内存泄露,如:
function foo(element,a,b){
element.onclick = function(){ /* 使用a和b */
}
函数本身的闭包引用了element,a,和b,即使从来没有使用到element;因为element也保存了指向该闭 包的引用,所以形成了一个环,不能被GC回收。在这种情况下,可以这样:
function foo(element,a,b){
element.onclick = bar(a,b);
}
function bar(a,b){
return function(){/* 使用a和b*/}
}
13,eval():只用于反序列化
eval()会造成令人困惑的语义,而且如果包含用户输入的字符串的时候也很危险。通常会有更好的方法来写这种需求的代码,所以通常不 用。但是,eval使得反序列化非常简单,所以可以接受。
反序列化是将一系列的字符转换成内存的数据结构的过程。例如,你可能将下面的对象写到一个文件中去:
users = [
{},
{},
...
];
要将这个对象读到内存中,就可以使用eval。
类似的,eval也可以简化解码RPC返回值的任务。如:
var userOnline = false;
var user = 'nusrat';
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://chat.google.com/isUserOnline?user=' + user, false);
xmlhttp.send('');
// Server returns:
// userOnline = true;
if (xmlhttp.status == 200) {
eval(xmlhttp.responseText);
}
// userOnline is now true.
14,with(){}:不要使用!
使用with会使代码更有迷惑性。因为with里面的对象可能会有和局部变量冲突的属性,所以可能会导致程序的原 意完全变化。例如:
with(foo){
var x = 3;
return x;
}
局部变量x可能与foo的属性冲突,甚至如果foo的那个属性有setter,还会导致其他的代码去执行。所以,不要使 用with!
15,this:只用在构造函数,方法,和构建闭包的时候
使用this容易使人产生疑惑。this可以指向全局对象(window),可以指向调用者,可以指向DOM节点,可以 指向新建的对象,可以指向别的对象(如果方法是用call或者apply调用的)。
因为this很容易出错,所以限制适用于以下情况:
16,for-in 循环
for-in循环经常被错误的用于遍历Array中的元素。错误原因在于并不只是遍历了从0到length-1的元素,而且 还遍历了原型链。以下是几个经常出错的:
function printArray(arr) {
for (var key in arr) {
print(arr[key]);
}
}
printArray([0,1,2,3]); // This works.
var a = new Array(10);
printArray(a); // This is wrong.
a = document.getElementsByTagName('*');
printArray(a); // This is wrong.
a = [0,1,2,3];
a.buhu = 'wine';
printArray(a); // This is wrong again.
a = new Array;
a[3] = 3;
printArray(a); // This is wrong again.
所以,要使用普通的遍历。
17,数组:不要将数组作为map,哈希,联合的数组
数组不允许使用非数字的索引,如果需要非数字的索引,可以使用Object。Array可以,是因为Array继承自 Object。
18,多行字符串:不要使用
不要这样:
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.';
19,字面数组和对象:建议使用
通常使用字面数组和对象来代替构造器。
Array构造器会因为参数不当而出错。
// Length is 3.
var a1 = new Array(x1, x2, x3);
// Length is 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);
// Length is 0.
var a4 = new Array();
因为这个原因,如果有人更改代码传了一个参数进去,而不是两个参数,代码可能会背离原意。
为了避免这种情况,这样:
var a = [x1, x2, x3];
var a2 = [x1, x2];
var a3 = [x1];
var a4 = [];
Object的构造器虽然没有这个问题,但是为了可读性和连贯性,建议使用字面对象。如:
var o = {};
var o2 = {
a: 0,
b: 1,
c: 2,
'strange key': 3
};
20,更改内置对象的prototype:禁止!
更改内置对象的原型是被严厉禁止的。
分享到:
相关推荐
#### 三、深入理解语言规范 ##### 1. 封装与基本类型 - **封装原则**:通过对象或函数封装实现模块化,提升代码复用性和安全性。 - **基本类型处理**:正确识别和使用JavaScript的基本数据类型,如`string`、`...
#### 二、JavaScript语言规范 ##### 1. 变量声明 - **使用`var`关键字**:每个变量声明必须使用`var`关键字,避免变量污染全局作用域。 - **示例**: ```javascript var myVariable = 10; ``` ##### 2. 常量 ...
1. JavaScript语言规范:在编写JavaScript代码时,必须遵循一定的规范来确保代码的可读性和可维护性。这部分内容通常会涉及到变量、常量、分号、嵌套函数等方面的具体使用规则。 2. 变量声明:在JavaScript中,声明...
**语言规范**:遵循ECMAScript标准。 **方法定义**:清晰地定义对象的方法。 **闭包**:利用闭包实现数据的封装和保护。 #### 7. **代码格式化与命名** **代码格式化**:统一代码风格,如缩进、括号使用等。 ...
#### JavaScript语言规范 ##### 1. 变量 **规定**:声明变量时必须使用`var`关键字。 **理由**:如果省略了`var`关键字,则变量会默认成为全局变量,这可能导致变量名冲突。此外,不使用`var`声明的变量其作用域...
**JavaScript语言规范:** 1. **变量声明**:所有变量必须使用`var`关键字声明。这样做可以避免变量自动成为全局对象的属性,降低命名冲突的风险,并能更明确地控制变量的作用域。 2. **常量**:常量应当使用大写...
1.7.2版本发布于2009年,虽然相对较旧,但仍然包含了许多关键的JavaScript语言特性,如函数、对象、数组、正则表达式等,以及一些高级特性如闭包和原型链。 使用"org.mozilla.javascript-1.7.2.jar",开发者可以...
JavaScript是一种解释型、弱类型、动态类型的编程语言,它基于ECMAScript规范,由ECMA国际维护。目前最新的版本是ECMAScript 2022。JavaScript主要应用于客户端的Web开发,用于增强用户界面,实现动态效果,以及与...
下面,我们将深入探讨这份规范中涉及的多个编程语言的指导原则和细节。 1. **Java**: - **命名规范**:变量、方法、类和包的命名应清晰、简洁且一致。通常,变量名用小驼峰式命名,类名用大驼峰式命名,包名全部...
### JavaScript语言精粹5 #### 一、JavaScript基础回顾与强化 **1.1 变量与数据类型** - **变量声明**: 在JavaScript中,可以使用`var`、`let`和`const`来声明变量。`var`具有函数作用域,而`let`和`const`具有...