为什么要编写可维护的javascript? 第一部分:编程风格程序是写给人读的,只是偶尔让计算机执行以下。 ——高德纳
一、基本的格式化1、缩进层级如何处理缩进是几乎所有语言首先讨论的,缩进甚至关系到软件工程师的价值观! 第一种缩进:使用制表符进行缩进。例如:jQuery核心风格,Dojo编程风格。 第二种缩进:使用空格符进行缩进。例如:Goolge的javascript规定使用两个空格缩进。 推荐:4个空格字符为一个缩进层级,可以在编辑器中配置Tab键插入4个空格。 2、语句结尾你加没加分号代码可能都会正常运行,没看到这里之前,你可能不知道这是分析器的自动分号插入机制(ASI)在偷偷的帮你干活。常言道:常在河边走,哪有不湿鞋?看看下面的代码。 function getData() {
return
{
text: '看看不加分号的后果!'
}
}
ASI会解析成下面的样子:
function getData() {
return ;
{
text: '看看不加分号的后果!'
};
}
所以如果调用上面的getData的方法,返回的就是undefined。但是这样不能全怪分号,谁让你把花括号写到下面一行的?(反正我看到有第一个花括号跟之前的语句不在一行的,我就要暴走。) //这段代码工作正常,尽管没有分号
function getData() {
return {
text: '看看不加分号的后果!'
}
}
3、行的长度: 倾向于80个字符。如果一行多于80个字符,应当在一个运算符(逗号,加号等)后换行。下一行应当增加两级缩进。 4、命名计算机科学只存在两个难题:缓存失效和命名。
ECMAScript遵照了小驼峰的命名法,所谓小驼峰,官方称之为“驼峰大小写命名法(Camel Case)”,是由小写字母开始的,后续每个单词首字母都大写。 //例如
var thisIsMyName;
变量命名前缀应该是名词。函数名前缀应该是动词。 //变量
var myName = 'chen';
//函数名
function getName() {
return myName;
}
5、常量在ECMAScript6之前,javascript中没有真正的常量概念。根据C语言的样子,约定使用大写字母和下划线来命名,下划线用以分割单词。 var MAX_COUNT = 10;
//现在我们应该也可以这样定义常量
const MAX_COUNT = 10;
6、构造函数构造函数的命名遵照大驼峰命名法(Pascal Case),为什么?因为跟本地语言保持一致的命名约定,new RegExp() ,正则本身就是一个内置的构造函数,看见大驼峰了木有? 科普一下:Pascal Case 和 Camel Case都表示“驼峰大小写”,区别在于: Pascal Case是以大写字母开始,所以也叫大驼峰,例如:AnotherName; Camel Case是以小写字母开始,之后的单词首字母大写,所以也叫小驼峰,例如:anotherName,之前在命名的那块提到过小驼峰。 7、直接量直接量可以这么理解,它是程序中可以直接使用的数据,没有进行特别的封装。 2 //数字直接量
"其心" //字符串直接量
[1,2,3] //数组直接量
true //布尔型直接量
{name: "其心"} //对象直接量
(function(){})() //函数直接量
/*分割线*/
new String("其心") //这就不是直接量
在直接量里着重说一下null ,我就经常误解它,用的很随意,现在我明确了解了,应该在下列场景中使用它。 直接量的用法简洁高效,是值得提倡的,这一点谨记。 二、注释1、单行注释单行注释有三种使用方法: // 好的写法
function print(){
// 控制台输出数字1
console.log(1);
}
//好的写法
// function print(){
// console.log(1);
// }
2、多行注释比较青睐Java风格的多行注释 /*
*这是一段注释
*这段注释包含两行文本
*/
多行注释之前也应该有一个空行,且缩进层级和其描述的代码保持一致。 3、文档注释多提一点就是文档的注释,多行注释以单斜线加双星号(/**)开始,接下来是描述信息,其中使用@符号来表示一个或多个属性。 /**
* 提交JSON数据
* @param actionUrl 交互的URL
* @param json JSON数据
* @param postSuccessFn 提交成功的回调函数
* @param postFailFn 提交失败的方法
* @param isAsync 是否异步提交,true:是
* @param timeout 请求时限
*/
三、语句和表达式首先说一点,见到下面两种写法,都是合法的JavaScript的代码,但是不提倡使用。 // 不好的写法
if(condition)
doSomething();
// 不好的写法
if(condition) doSomething();
1、花括号的对齐方式第一种风格是,将左花括号放置在块语句中第一句代码的末尾。这种风格继承自Java。 if (condition) {
doSomething();
}else {
doSomethingElse();
}
第二种风格是,将花括号放置于块语句首行的下一行。这是随着C#流行起来的。 if (condition)
{
doSomething();
}else
{
doSomethingElse();
}
为了避免导致错误的分号自动插入(还记得之前说过的“ASI”么),推荐使用第一种花括号对齐方式。 2、switch对于switch的缩进之类可以直接用编辑器默认的,只提一点就是,如果程序没有默认的行为时,default是可以被省略的。 四、变量、函数和运算符1、变量 建议将局部变量的定义作为函数内第一条语句,推荐使用单个var语句,每个变量的初始化独占一行。对于没有初始化的变量来说,它们应当出现在var语句的尾部。 function doSomething(items) {
var value = 10,
result = value 10,
i,
len;
for(i = 0,len = items.length; i < len; i ){
doOtherSomething(items[i]);
}
}
2、函数声明需要注意,函数声明应当在条件语句的外部使用。例如: //不好的写法,大部分浏览器会自动使用第二个声明,并不会根据condition来做判断。
if (condition) {
function doSomething() {
alert("Hi!");
}
} else {
function doSomething() {
alert("Yo!");
}
}
3、相等JavaScript具有强制类型转换的机制。 // 比较数字5和字符串5
console.log(5 == "5"); // true
// 比较数字25和十六进制的字符串25
console.log(25 == "0x19"); // true
// 比较数字1和true
console.log(1 == true); // true
// 比较数字0和false
console.log(0== false); // true
//比较数字2和true
console.log(2 == true); // false
五、避免“空比较”1、检测原始值JavaScript有5中简单的原始类型:字符串、数字、布尔值、null和undefined。最佳的选择是用typeof运算符,返回一个值的类型的字符串。 用typeof检测一下4种原始值类型是非常安全的。 //检测字符串
if (typeof name === "string") {
anotherName = name.substring(3);
}
//检测数字
if (typeof count === "number") {
updateCount(count);
}
//检测布尔值
if (typeof found === "boolean" && found){
message("Found!");
}
//检测underfined
if (typeof MyApp=== "undefined") {
MyApp = {};
}
2、检测引用值引用值也称为对象,检测某个引用值的类型的官方最好的方法是使用instanceof运算符。但是它不仅检测构造这个对象的构造器,还检测原型链。因为每个对象都继承自Object,因此每个对象的 value instanceof Object 都会返回true。 var now = new Date();
console.log(now instanceof object); // true
console.log(now instanceof Date) // true
3、检测数组最开始是判断sort()方法在不在。 function isArray(value) {
return typeof value.sort === "function";
}
然后有了一种比较优雅的解决方案。 function isArray() {
return Object.prototype.toString.call(value) === "[object Array]";
}
再后来ECMAScript5将Array.isArray()正式引入JavaScript。 4、检测属性判断属性是否存在的最好的方法是使用in运算符。in运算符只会简单地判断属性是否存在,而不会去读属性的值。但是检测出来的属性可以是对象自身的,也可以是继承来的。 var object = {
count: 0,
related: null
};
if ("count" in object) {
//这里的代码会执行
}
如果只检查对象自身的某个属性是否存在,就使用hasOwnProperty()方法。 六、配置数据分离配置数据类似: 七、错误类型Error: 所有的错误类型。实际上引擎从来不会抛出该类型的错误。 EvalError: 通过eval()函数执行代码发生错误时抛出。 RangeError: 一个数字超出它的边界时抛出。 ReferenceError: 期望的对象不存在时抛出。 SyntaxError: 给eval()函数传递的代码中有语法错误时抛出。 TypeError: 变量不是期望的类型时抛出。
八、阻止修改属性Object.preventExtension(); // 锁定对象
Object.isExtensible(); // 判断对象是否被锁定
Object.seal(); // 密封对象
Object.isSealed(); // 检测一个对象是否已被密封
Object.freeze(); // 冻结对象
Object.isFrozen(); // 判断一个对象是否已被冻结 来源:https://www./content-1-665601.html
|