《编写可维护的JavaScript》读书笔记之编程风格-基本的格式化

基本的格式化

命名

“计算机科学只存在两个难题:缓存失效和命名。”—— Phil Karlton

只要是书写代码,都会涉及变量和函数,因此变量和函数命名对于增强代码可读性至关重要。JavaScript 语言的核心 ECMAScript,即是遵照了驼峰式大小写命名法:小写字母开始,后续每个单词首字母都大写。

var thisIsMyName;
var doSomething;

【注意】:驼峰式大小写分为小驼峰式(Camel Case),以及大驼峰式(Pascal Case)。上面所举例子就是小驼峰式,而大驼峰式是首字母大写。

  • Google、SproutCore 编程风格指南以及 Dojo 编程风格:推荐使用小驼峰式命名法。

在 2000 年左右,流行另外一种命名方法——匈牙利命名法。名字之前冠以类型标识符前缀,比如 sName 表示字符串,iCounnt 表示整数。不过这种风格已经是明日黄花风光不再,当前主流的编程规范都不推荐这种命名法。

变量和函数

变量名以及函数名都应当总是遵守驼峰大小写命名法。变量名前缀应当是名词,而函数名前缀应当是动词。

// 好的写法
var count = 10;
var myName = "Spirit";
var found = true;

// 不好的写法:变量看起来像函数
var getCount = 10;
var isFount = true;

// 好的写法
function getName() {
    return myName;
}

// 不好的写法:函数看起来像变量
function theName() {
    return myName;
}

【建议】:

  1. 命名长度应该尽可能短,并抓住要点;
  2. 尽量在变量名中体现出值的数据类型;
  3. 避免使用没有意义的命名。

对于函数和方法命名来说,第一个单词应该是动词,这里有一些使用动词常见的约定。

动词 含义
can 函数返回一个布尔值
has 函数返回一个布尔值
is 函数返回一个布尔值
get 函数返回一个非布尔值
set 函数用来保存一个值
if(isEnabled()) {
    setName("Spirit");
}

if(getName() === "Spirit") {
    doSomething();
}

尽管这些函数命名细则并没有被归纳入当下流行的编程风格中,但在很多流行的库中,JavaScript 开发者会发现存在不少这种“伪标准”(pseudostandard)。

jQuery 没有遵循这种函数命名约定,一部分在于 jQuery 中方法的使用方式,很多方法同时用作 getter 和 setter。尽管如此,还是推荐使用动词作为函数名前缀。

常量:

在 ECMAScript 6 之前,JavaScript 中并没有真正的常量概念。然而,这并不能阻止开发者将变量用作常量。为了区分普通的变量和常量,一种通用的命名约定应运而生。

// 使用大写字母和下划线来命名,下划线用以分隔单词
var MAX_COUNT = 10;
var URL = "http://www.baidu.com";

构造函数:

在 JavaScript 中,构造函数只不过是前面冠以 new 运算符的函数(在 ES6 之前),用来创建对象。

JavaScript 语言本身已经包含了许多内置构造函数,比如 Object 和 RegExp,同样开发者也可以创建自己的构造函数来生成新类型。

【推荐】:构造函数的命名遵照大驼峰式命名法。

// 好的做法
function Person(name) {
    this.name = name;
}

Person.prototype.sayName = function () {
    alert(this.name);
};

var me = new Person("spirit");

// 不正确的写法
var me = Person("Spirit");

【说明】:Crockford 编程规范、Google 的 JavaScript 风格指南以及 Dojo 编程风格指南都推荐这种实践。如果构造函数的首字母不是大写的,或者构造函数之前没有 new 运算符,JSLint 都会给出警告。而 JSHint 只有开启 newcap 选项后,才会对首字母不是大写的构造函数给出警告。

直接量(字面量)

JavaScript 中包含一些类型的原始值:字符串、数字、布尔值、null 和 undefined。同样也包含对象直接量和数组直接量。这其中,只有布尔值是自解释(self-explanatory)的,其他的类型或多或少都需要思考一下它们如何才能更精确地表示出来。

字符串:

在 JavaScript 中,字符串是独一无二的。字符串可以用双引号括起来,也可以用单引号括起来。

var name = "Spirit, \"Hello!\"";
var name2 = 'Spirit, "Hello!"';

和 Java、PHP 这些语言不同,使用单引号括起字符串和双引号括起字符串在功能上并无不同。除了内部出现字符串界定符(string delimiter)时需要转义之外,两种做法在功效上完全一致。我们需要关心的是,代码从头到尾保持一种风格。

  • Crockford 编程规范:双引号。
  • jQuery 核心风格指南:双引号。
  • Google:单引号。

【注意】:创建多行字符串时,请使用字符串连接符(+)。

// 非法的 JavaScript 语法,但能在 JS 引擎中正常工作
var longStr = "Here's the story, of a man \
            named Spirit.";

// 好的写法
var longStr = "Here's the story, of a man" +
            " named Spirit.";

数字:

在 JavaScript 中的数字类型只有一种,因为所有数字形式——整数和浮点数——都存储为相同的数据类型。

有一些数字直接量格式来表示不同的数据格式,其中大部分写法都很好用,但也有一些写法有问题。

// 整数
var count = 10;

// 小数
var price = 10.0;
var price = 10.00;

// 不推荐的写法:没有小数部分
var price = 10.;

// 不推荐的写法:没有整数部分
var price = .1;

// 不推荐的写法:八进制写法已经被弃用了
var num = 010;

// 十六进制写法
var num = 0xA2;

// 科学计数法
var num = 1e23; // 等价于 10 的23次方

小数的写法请尽量不要省略小数以及整数部分。因为这存在一个问题:很难搞清楚是不小心丢掉了还是刻意为之。为了避免歧义,尽量将其书写完整。

长久以来,JavaScript 支持八进制数字写法是很多错误和歧义的根源。数字直接量 010 不是表示 10,而是表示八进制中的 8。大多数开发者对八进制格式并不熟悉,也很少用到,所以最好的做法是在代码中禁止八进制直接量。

null:

null 是一个特殊值,容易将其和 undefined 搞混。我们需要明确在什么场景下使用 null:

  • 用来初始化一个变量,这个变量可能赋值为一个对象。
  • 用来和一个已经初始化的变量比较,这个变量可以是也可以不是一个对象。
  • 当函数的参数期望是对象时,用作参数传入。
  • 当函数的返回值期望是对象时,用作返回值传出。

不应当使用 null 的场景:

  • 不要使用 null 来检测是否传入了某个参数。
  • 不要用 null 来检测一个未初始化的变量。
// 好的用法
var person = null;

function getPerson() {
    if(condition) {
        return new Person("Spirit");
    } else {
        return null;
    }
}

var person = getPerson();
if(person !== null) {
    doSomething();
}

// 不好的用法
var person;
if(person !== null) {
    doSomething();
}

function doSomething(arg1, arg2, arg3, arg4) {
    if(arg4 != null) {
        doSomethingElse();
    }
}

理解 null 最好的方式是将它当做对象的占位符。

undefined:

undefined 是一个特殊值。其中一个令人困惑之处在于 null == undefined 的结果是 true。然而,这两个值的用途却各不相同。那些没有被初始化的变量都有一个初始值,即 undefined,表示该变量等待被赋值。

// 不好的写法
var person;
console.log(person === undefined); // true

尽管这段代码能正常工作,但建议还是避免在代码中使用 undefined。因为这个值常常和返回 undefined 的 typeof 运算符混淆。不管是值为 undefined 的变量以及未声明的变量,typeof 运算符返回的结果都为 undefined。

// foo 未被声明
var person;
console.log(typeof person); // undefined
console.log(typeof foo); // undefined

也就是说无法区分值为 undefined 的变量以及未声明的变量

【问】如何解决这个会产生歧义的问题呢?
【答】通过禁止使用 undefined,可以有效确保只在一种情况下(未声明变量)typeof 返回 undefined。禁止使用 undefined 意味着我们要将未赋值的变量都赋予初值。

对象直接量:

创建对象最流行的一种做法是使用对象直接量,在直接量中直接写出所有属性,这种方式可以取代先显式地创建 Object 的实例然后添加属性的这种做法。

对象直接量允许你将所有的属性都括在一对花括号内。当定义对象直接量时,常常在第一行包含左花括号,每一个属性的键值对都独占一行,并保持一个缩进,最后右花括号也独占一行。

// 不好的写法
var book = new Object();
book.title = "Database";
book.author = "spirit";

// 好的写法
var book = {
    title : "Database",
    author : "Spirit"
}

尽管没有归纳入文档中,Google 以及 Crockford 编程规范推荐使用这种写法。

数组直接量:

使用两个方括号将数组初始元素括起来,来替代使用 Array 构造函数的方式。

// 不好的写法
var colors = new Array("red", "green", "blue");
var numbers = new Array(1, 2, 3, 4);

// 好的写法
var colors = ["red", "green", "blue"];
var numbers = [1, 2, 3, 4];

Google 以及 Crockford 编程规范推荐这种写法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • 0. 写在前面 当你开始工作时,你不是在给你自己写代码,而是为后来人写代码。 —— Nichloas C. Zak...
    康斌阅读 5,318评论 1 42
  • JavaScript,通常缩写为 JS,是一种解释执行的编程语言。它是现在最流行的脚本语言之一。 JavaScri...
    神齐阅读 4,860评论 1 32
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,122评论 0 21
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,182评论 0 3
  • 问题 一年一度的欧洲冠军杯比赛已经落幕,其在初赛阶段采用循环制,设共有n队参加,初赛共进行n-1天,每队要和其他各...
    Stroman阅读 567评论 0 1