yjxf8285@qq.com

转载

JS编码风格

Posted By 刘晓帆 | 45 views

介绍

作者根据Robert C. Martin《代码整洁之道》总结了适用于JavaScript的软件工程原则《Clean Code JavaScript》

本文是对其的翻译。

不必严格遵守本文的所有原则,有时少遵守一些效果可能会更好,具体应根据实际情况决定。这是根据《代码整洁之道》作者多年经验整理的代码优化建议,但也仅仅只是一份建议。

软件工程已经发展了50多年,至今仍在不断前进。现在,把这些原则当作试金石,尝试将他们作为团队代码质量考核的标准之一吧。

最后你需要知道的是,这些东西不会让你立刻变成一个优秀的工程师,长期奉行他们也并不意味着你能够高枕无忧不再犯错。千里之行,始于足下。我们需要时常和同行们进行代码评审,不断优化自己的代码。不要惧怕改善代码质量所需付出的努力,加油。

变量

使用有意义,可读性好的变量名

反例:

正例:

回到目录

使用ES6的const定义常量

反例中使用”var”定义的”常量”是可变的。

在声明一个常量时,该常量在整个程序中都应该是不可变的。

反例:

正例:

回到目录

对功能类似的变量名采用统一的命名风格

反例:

正例:

回到目录

使用易于检索名称

我们需要阅读的代码远比自己写的要多,使代码拥有良好的可读性且易于检索非常重要。阅读变量名晦涩难懂的代码对读者来说是一种相当糟糕的体验。 让你的变量名易于检索。

反例:

正例:

回到目录

使用说明变量(即有意义的变量名)

反例:

正例:

回到目录

不要绕太多的弯子

显式优于隐式。

反例:

正例:

回到目录

避免重复的描述

当类/对象名已经有意义时,对其变量进行命名不需要再次重复。

反例:

正例:

回到目录

避免无意义的条件判断

反例:

正例:

回到目录

函数

函数参数 (理想情况下应不超过2个)

限制函数参数数量很有必要,这么做使得在测试函数时更加轻松。过多的参数将导致难以采用有效的测试用例对函数的各个参数进行测试。

应避免三个以上参数的函数。通常情况下,参数超过两个意味着函数功能过于复杂,这时需要重新优化你的函数。当确实需要多个参数时,大多情况下可以考虑这些参数封装成一个对象。

JS定义对象非常方便,当需要多个参数时,可以使用一个对象进行替代。

反例:

正例:

回到目录

函数功能的单一性

这是软件功能中最重要的原则之一。

功能不单一的函数将导致难以重构、测试和理解。功能单一的函数易于重构,并使代码更加干净。

反例:

正例:

回到目录

函数名应明确表明其功能

反例:

正例:

回到目录

函数应该只做一层抽象

当函数的需要的抽象多于一层时通常意味着函数功能过于复杂,需将其进行分解以提高其可重用性和可测试性。

反例:

正例:

回到目录

移除重复的代码

永远、永远、永远不要在任何循环下有重复的代码。

这种做法毫无意义且潜在危险极大。重复的代码意味着逻辑变化时需要对不止一处进行修改。JS弱类型的特点使得函数拥有更强的普适性。好好利用这一优点吧。

反例:

正例:

回到目录

采用默认参数精简代码

反例:

正例:

回到目录

使用Object.assign设置默认对象

反例:

正例:

回到目录

不要使用标记(Flag)作为函数参数

这通常意味着函数的功能的单一性已经被破坏。此时应考虑对函数进行再次划分。

反例:

正例:

回到目录

避免副作用

当函数产生了除了“接受一个值并返回一个结果”之外的行为时,称该函数产生了副作用。比如写文件、修改全局变量或将你的钱全转给了一个陌生人等。

程序在某些情况下确实需要副作用这一行为,如先前例子中的写文件。这时应该将这些功能集中在一起,不要用多个函数/类修改某个文件。用且只用一个service完成这一需求。

反例:

正例:

回到目录

不要写全局函数

在JS中污染全局是一个非常不好的实践,这么做可能和其他库起冲突,且调用你的API的用户在实际环境中得到一个exception前对这一情况是一无所知的。

想象以下例子:如果你想扩展JS中的Array,为其添加一个diff函数显示两个数组间的差异,此时应如何去做?你可以将diff写入Array.prototype,但这么做会和其他有类似需求的库造成冲突。如果另一个库对diff的需求为比较一个数组中收尾元素间的差异呢?

使用ES6中的class对全局的Array做简单的扩展显然是一个更棒的选择。

反例:

正例:

回到目录

采用函数式编程

函数式的编程具有更干净且便于测试的特点。尽可能的使用这种风格吧。

反例:

正例:

回到目录

封装判断条件

反例:

正例:

回到目录

避免“否定情况”的判断

反例:

正例:

回到目录

避免条件判断

这看起来似乎不太可能。

大多人听到这的第一反应是:“怎么可能不用if完成其他功能呢?”许多情况下通过使用多态(polymorphism)可以达到同样的目的。

第二个问题在于采用这种方式的原因是什么。答案是我们之前提到过的:保持函数功能的单一性。

反例:

正例:

回到目录

避免类型判断(part 1)

JS是弱类型语言,这意味着函数可接受任意类型的参数。

有时这会对你带来麻烦,你会对参数做一些类型判断。有许多方法可以避免这些情况。

反例:

正例:

回到目录

避免类型判断(part 2)

如果需处理的数据为字符串,整型,数组等类型,无法使用多态并仍有必要对其进行类型检测时,可以考虑使用TypeScript。

反例:

正例:

回到目录

避免过度优化

现代的浏览器在运行时会对代码自动进行优化。有时人为对代码进行优化可能是在浪费时间。

这里可以找到许多真正需要优化的地方

反例:

正例:

回到目录

删除无效的代码

不再被调用的代码应及时删除。

反例:

正例:

回到目录

对象和数据结构

使用getters和setters

JS没有接口或类型,因此实现这一模式是很困难的,因为我们并没有类似publicprivate的关键词。

然而,使用getters和setters获取对象的数据远比直接使用点操作符具有优势。为什么呢?

  1. 当需要对获取的对象属性执行额外操作时。
  2. 执行set时可以增加规则对要变量的合法性进行判断。
  3. 封装了内部逻辑。
  4. 在存取时可以方便的增加日志和错误处理。
  5. 继承该类时可以重载默认行为。
  6. 从服务器获取数据时可以进行懒加载。

反例:

正例:

回到目录

让对象拥有私有成员

可以通过闭包完成

反例:

正例:

回到目录

单一职责原则 (SRP)

如《代码整洁之道》一书中所述,“修改一个类的理由不应该超过一个”。

将多个功能塞进一个类的想法很诱人,但这将导致你的类无法达到概念上的内聚,并经常不得不进行修改。

最小化对一个类需要修改的次数是非常有必要的。如果一个类具有太多太杂的功能,当你对其中一小部分进行修改时,将很难想象到这一修够对代码库中依赖该类的其他模块会带来什么样的影响。

反例:

正例:

回到目录

开/闭原则 (OCP)

“代码实体(类,模块,函数等)应该易于扩展,难于修改。”

这一原则指的是我们应允许用户方便的扩展我们代码模块的功能,而不需要打开js文件源码手动对其进行修改。

反例:

正例:

回到目录

利斯科夫替代原则 (LSP)

“子类对象应该能够替换其超类对象被使用”。

也就是说,如果有一个父类和一个子类,当采用子类替换父类时不应该产生错误的结果。

反例:

正例:

回到目录

接口隔离原则 (ISP)

“客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。”

在JS中,当一个类需要许多参数设置才能生成一个对象时,或许大多时候不需要设置这么多的参数。此时减少对配置参数数量的需求是有益的。

反例:

正例:

回到目录

依赖反转原则 (DIP)

该原则有两个核心点:
1. 高层模块不应该依赖于低层模块。他们都应该依赖于抽象接口。 2. 抽象接口应该脱离具体实现,具体实现应该依赖于抽象接口。

反例:

正例:

回到目录

使用ES6的classes而不是ES5的Function

典型的ES5的类(function)在继承、构造和方法定义方面可读性较差。

当需要继承时,优先选用classes。

但是,当在需要更大更复杂的对象时,最好优先选择更小的function而非classes。

反例:

正例:

回到目录

使用方法链

这里我们的理解与《代码整洁之道》的建议有些不同。

有争论说方法链不够干净且违反了德米特法则,也许这是对的,但这种方法在JS及许多库(如JQuery)中显得非常实用。

因此,我认为在JS中使用方法链是非常合适的。在class的函数中返回this,能够方便的将类需要执行的多个方法链接起来。

反例:

正例:

回到目录

优先使用组合模式而非继承

在著名的设计模式一书中提到,应多使用组合模式而非继承。

这么做有许多优点,在想要使用继承前,多想想能否通过组合模式满足需求吧。

那么,在什么时候继承具有更大的优势呢?这取决于你的具体需求,但大多情况下,可以遵守以下三点:

  1. 继承关系表现为”是一个”而非”有一个”(如动物->人 和 用户->用户细节)
  2. 可以复用基类的代码(“Human”可以看成是”All animal”的一种)
  3. 希望当基类改变时所有派生类都受到影响(如修改”all animals”移动时的卡路里消耗量)

反例:

正例:

回到目录

测试

一些好的覆盖工具.

一些好的JS测试框架

单一的测试每个概念

反例:

正例:

回到目录

并发

用Promises替代回调

回调不够整洁并会造成大量的嵌套。ES6内嵌了Promises,使用它吧。

反例:

正例:

回到目录

Async/Await是较Promises更好的选择

Promises是较回调而言更好的一种选择,但ES7中的async和await更胜过Promises。

在能使用ES7特性的情况下可以尽量使用他们替代Promises。

反例:

正例:

回到目录

错误处理

错误抛出是个好东西!这使得你能够成功定位运行状态中的程序产生错误的位置。

别忘了捕获错误

对捕获的错误不做任何处理是没有意义的。

代码中try/catch的意味着你认为这里可能出现一些错误,你应该对这些可能的错误存在相应的处理方案。

反例:

正例:

不要忽略被拒绝的promises

理由同try/catch.

反例:

正例:

回到目录

格式化

格式化是一件主观的事。如同这里的许多规则一样,这里并没有一定/立刻需要遵守的规则。可以在这里完成格式的自动化。

大小写一致

JS是弱类型语言,合理的采用大小写可以告诉你关于变量/函数等的许多消息。

这些规则是主观定义的,团队可以根据喜欢进行选择。重点在于无论选择何种风格,都需要注意保持一致性。

反例:

正例:

回到目录

调用函数的函数和被调函数应放在较近的位置

当函数间存在相互调用的情况时,应将两者置于较近的位置。

理想情况下,应将调用其他函数的函数写在被调用函数的上方。

反例:

正例:

回到目录

注释

只对存在一定业务逻辑复制性的代码进行注释

注释并不是必须的,好的代码是能够让人一目了然,不用过多无谓的注释。

反例:

正例:

回到目录

不要在代码库中遗留被注释掉的代码

版本控制的存在是有原因的。让旧代码存在于你的history里吧。

反例:

正例:

回到目录

不需要版本更新类型注释

记住,我们可以使用版本控制。废代码、被注释的代码及用注释记录代码中的版本更新说明都是没有必要的。

需要时可以使用git log获取历史版本。

反例:

正例:

回到目录

避免位置标记

这些东西通常只能代码麻烦,采用适当的缩进就可以了。

反例:

正例:

回到目录

避免在源文件中写入法律评论

将你的LICENSE文件置于源码目录树的根目录。

反例:

正例:

b

Read More

HTML/CSS

HTML标签-英文全称对照表

Posted By 刘晓帆 | 98 views

HTML标签 英文全称 中文释义
a Anchor
abbr Abbreviation 缩写词
acronym Acronym 取首字母的缩写词
address Address 地址
dfn Defines a Definition Term 定义定义条目
kbd Keyboard 键盘(文本)
samp Sample 示例(文本
var Variable 变量(文本)
tt Teletype 打印机(文本)
code Code 源代码(文本)
pre Preformatted 预定义格式(文本 )
blockquote Block Quotation 区块引用语
cite Citation 引用
q Quotation 引用语
strong Strong 加重(文本)
em Emphasized 加重(文本)
b Bold 粗体(文本)
i Italic 斜体(文本)
big Big 变大(文本)
small Small 变小(文本)
sup Superscripted 上标(文本)
sub Subscripted 下标(文本)
bdo Direction of Text Display 文本显示方向
br Break 换行
center Centered 居中(文本)
font Font 字体
u Underlined 下划线(文本)
s/ strike Strikethrough 删除线
div Division 分隔
span Span 范围
ol Ordered List 排序列表
ul Unordered List 不排序列表
li List Item 列表项目
dl Definition List 定义列表
dt Definition Term 定义术语
dd Definition Description 定义描述
del Deleted 删除(的文本)
ins Inserted 插入(的文本)
h1~h6 Header 1 to Header 6 标题1到标题6
p Paragraph 段落
hr Horizontal Rule 水平尺
href hypertext reference 超文本引用
alt alter 替用(一般是图片显示不出的提示)
src Source 源文件链接
cell cell
cellpadding cellpadding 巢补白
cellspacing cellspacing 巢空间
nl navigation lists 导航列表
tr table row 表格中的一行
th table header cell 表格中的表头
td table data cell 表格中的一个单元格
Read More

Plugins/Tools

浏览器文本复制到剪贴板

Posted By 刘晓帆 | 696 views

github上面的这个复制功能如何实现的呢?

1

 

 

 

解决方案: clipboardjs插件

插件官网:https://clipboardjs.com/

使用方法:
HTML

<div className="testtitle copy-btn btn" data-clipboard-text="http://www.baidu.com">copy</div>

JS

var clipboard = new Clipboard('.btn');
clipboard.on('success', function (e) {
    console.info('Action:', e.action);
    console.info('Text:', e.text);
    console.info('Trigger:', e.trigger);
    e.clearSelection();
});
Read More

OS

win10下磁盘100%的解决方案

Posted By 刘晓帆 | 377 views

升级到win10后发现系统经常会有卡顿的感觉,原因主要是以下2点
1 oneDrive
2 家庭组

上面两个功能会十分频繁的读写硬盘,所以还得禁用掉比较。

1 oneDrive的禁用方法比较简单,直接右键图标退出即可。
2 家庭组需要禁用掉系统服务,步骤如下:
进入计算机管理-服务,找到“HomeGoup Listener”与“HomeGroup Provider”两项服务,右键单击进入“属性”,停止运行后设置启动类型为“禁用”。

Read More
  • win10下磁盘100%的解决方案已关闭评论
  • 6 months ago

Plugins/Tools

Material Design在线配色工具

Posted By 刘晓帆 | 694 views

工具地址:http://www.materialpalette.com/

之前对比过很多配色工具,Material Design提供的方案还是很漂亮的,非常喜欢这种风格。

Material Design 的一些重要功能包括 系统字体Roboto的升级版本 ,同时颜色更鲜艳,动画效果更突出。杜拉特还简要谈到了新框架的一些变化——这个新框架也于今天在 google.com/design 公开发布。谷歌的想法是让谷歌平台上的开发者掌握这个新框架,从而让所有应用就有统一的外观,就像是苹果向开发者提出的设计原则一样。谷歌还基于这种新的设计语言对本公司旗舰应用进行了重新设计,包括安卓和网页端的Gmail和Calendar。大家可能还会记得,看到过有关这些变动的文章, 有些博客 已经掌握了外泄截屏,显示经过了重新设计的Gmail,界面更干净、更简约。在安卓平台上,这种新界面被称为Material,支持各种新动画效果,具有内置的实时UI阴影,以及可在不同屏幕之间切换的hero元素。

Read More
  • Material Design在线配色工具已关闭评论
  • 8 months ago

Plugins/Tools

HTML to JSX 转换工具

Posted By 刘晓帆 | 1,141 views

提供一个html转jsx的在线工具。
地址:http://liuxiaofan.com/tojsx/

说明:
场景,进行react代码重构的时候,要把之前写好大量的html代码复制到js文件里面。因为jsx的一些语法规则导致了要修改很多HTML标签属性名称,诸如class变成className之类的。这时候你可能会想,如果有一个能够一键转换的工具就好了。把普通的html代码复制到左边的框框里面,然后右边的窗口就会出现转译好的jsx代码……

Read More

Plugins/Tools

HTML5 Sortable – jQuery拖放排序插件使用方法

Posted By 刘晓帆 | 665 views

插件下载地址:http://liuxiaofan.com/download/html5sortable.tar.gz

特点

  • 很轻量,压缩后体积小于1KB
  • 基于HTML5原生的darg和dorp方法
  • 支持列表和网格风格布局2种布局
  • 文档类似于jQuery UI的sortable插件
  • 兼容IE 5.5+, Firefox 3.5+, Chrome 3+, Safari 3+, and Opera 12+

如何使用?

基本的DOM结构和运行脚本。

<ul class="sortable">
 <li>Item 1
 <li>Item 2
 <li>Item 3
 <li>Item 4
</ul>
<script src="jquery.sortable.js"></script>
<script>
 $('.sortable').sortable();
</script>

使用了2种样式用于区别拖拽中.sortable-dragging和拖放占位.sortable-placeholder。

使用 sortupdate 事件,触发条件为排序发生了变化。

$('.sortable').sortable().bind('sortupdate', function() {
   //当用户的dom位置改变后和排序完成之后触发
});

使用items选项用来指定哪些项目可以被拖放

$('.sortable').sortable({
    items: ':not(.disabled)'
});

使用handle选项指定一个可拖拽的小把手

$('.sortable').sortable({
    handle: '.handle'
});

使用connectWith选项,创建一个有关联的列表

$('#sortable1, #sortable2').sortable({
    connectWith: '.connected'
});

销毁方法

$('.sortable').sortable('destroy');

使其无效化方法

$('.sortable').sortable('disable');

使其有效化方法

$('.sortable').sortable('enable');
Read More
  • HTML5 Sortable – jQuery拖放排序插件使用方法已关闭评论
  • 8 months ago

JavaScript

直接事件和委托事件

Posted By 刘晓帆 | 1,141 views

有人问过我一个问题,如下

$('ul li').on('click', function () {
   //todo 
});
$('ul').on('click','li', function () {
    //todo 
});

上面这2段代码的区别是什么?

其实jquery的官网文档中有详细的解释,第1段的意思是把事件直接绑定在li上面,如果有1000个li,那么就相当于绑定了1000次li。而且只能绑定到文档中已经存在的Li上面,后续添加的li是绑定不上的,比如通过ajax添加进去的新的li。 这就是直接事件绑定。
第2段是委托事件,也叫代理事件,只绑定了一次事件到li上面,也可以监听到后续添加的li。

Read More

Plugins/Tools

iScroll 5 API 中文版

Posted By 刘晓帆 | 1,147 views

前言

最近项目上需要使用iScroll,在中文圈里找了找,只找到了iScroll 4的中文版API。加上最近开始使用github(准确说,github账号是很多年前注册的,一直在企业应用里摸爬滚打,荒废了账号很长时间,是理由吗?是理由吗?),出于对开源社区的敬意,我突然觉得应该做点啥,于是先挑一个简单点儿的,把iScroll 5的API翻译一下,方便中文用户使用。

搭后语

iScroll对于我来讲典型的应用场景位于移动设备的App,基于Cordova/Phonegap + JQM + iScroll开发移动设备上的App,对于以数据呈现为主体的企业应用来讲无疑是一个多快好省的解决方案。这三驾马车前两个可以堂而皇之的称之为开发框架,iScroll只能称之为工具,尽管如此,iScroll带来的强大的滚动功能,能节省我们在项目开发上的部分时间(这也是开源社区的力量),所以也值得我花时间理解作者的代码和文档。如果您认同这种功劳苦劳,请到github上给我一个star。由于才疏学浅,在翻译过程中难免会有错误或者瑕疵,请在issure中提出,我会及时更正。
(更多…)

Read More

HTML/CSS

CSS3 点击放大动画实例

Posted By 刘晓帆 | 1,474 views

需求:点击商品图片右上的收藏按钮触发放大动画;
技术重点css3:@keyframes animation

提示:你可以先修改部分代码再运行。

Read More