博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript 代码简洁之道
阅读量:5915 次
发布时间:2019-06-19

本文共 6116 字,大约阅读时间需要 20 分钟。

想必大家都有接手过老旧项目,它的代码风格怎么样?可能大部分同学都会无力吐槽吧。笔者认为一份代码的好坏,先不管其实现如何,至少其 可读性 得保证,才能算得上好代码。有些还没有意识到 可读性代码 所带来好处的同学,可能经常会遇到上周才写的代码,今天打开项目一看,卧槽,这个 ? 一样的代码是我写的吗?

笔者的 代码洁癖 有点严重,所以平时对自己写的代码也有比较高的要求,至少在 可读性 上算是比较能保证。下面将分享一些代码 可读性简洁性 方面的一些技巧。

命名

相信大家比较多的吐槽就是变量的命名,以至于出现类似 这种辅助声明变量名的神器,所以平时在项目中如何做到好的命名呢。

其实大多数的变量赋值后都不会再改变(重新赋值),所以笔者会优先使用 const 而不是 let,确实无法避免需要赋值多次才用 let

常量都应该命名

// Badstatic({    maxAge: 28800000, // what ???});// Goodconst EIGHT_HOURS_IN_MILLISECOND = 28800000;// orconst EIGHT_HOURS_IN_MILLISECOND = 8 * 60 * 60 * 1000;static({    maxAge: EIGHT_HOURS_IN_MILLISECOND,});// Bad$(document).on('keydown', event => {    // 27 是什么鬼???    if(event.keyCode === 27) {        // do something ...    }});// Good$(document).on('keydown', event => {    const KEY_ESC = 27;    if(event.keyCode === KEY_ESC) {        // do something ...    }});复制代码

有意义的命名

// Badconst n = '大板栗';const a = 18;// Goodconst name = '大板栗';const age = 18;复制代码

减少命名冗余

// Badconst favoriteList = [];const getCurrentUserData = () => {};// Goodconst favorites = [];const getCurrentUser = () => {};复制代码

顾名思义

单看函数名就应该知道功能是什么。

// Badfunction fetchAtls() {}// Goodfunction fetchArticles() {}// orfunction getArticles() {}复制代码

函数

简化代码

利用三目运算符和 ES6+ 语法简化代码

// Bad$('.js-button').on('click', function() {    var name = '开始';    if ($(this).hasClass('again')) {        name = '再玩一次';    }    app.track('按钮', name);});// Good$('.js-button').on('click', function() {    const again = $(this).hasClass('again');    app.track(again ? '再玩一次' : '开始');});// Badconst celebrationDayChange = isSameDay => {    if (isSameDay) {        $dateSelect.addClass('hide');    } else {        $dateSelect.removeClass('hide');    }};// Goodconst celebrationDayChange = isSameDay => {    const action = isSameDay ? 'addClass' : 'removeClass';    $dateSelect[action]('hide');};复制代码

函数参数

函数的参数尽量简短,如有 3 个以上建议直接换成对象的方式:

// Badfunction publish(title, author, except, content) {}// 必须知道参数位置信息publish('title', '大板栗', 'an excellent article', 'This is content.');// Goodfunction publish({title, author, except, content}) {}publish({    title: 'title',    author: '大板栗',    except: 'an excellent article',    content: 'This is content.',});复制代码

设置对象默认属性

// Badconst options = {    name: '大板栗',    logo: 'Logo.png',    theme: 'dark',};function createApp(options = {}) {    options.name = options.name || 'App';    options.logo = options.logo || 'Logo.png';    options.theme = options.theme || 'light';}// Goodfunction createApp(options = {}) {    options = Object.assign({        name: 'App',        logo: 'Logo.png',        theme: 'light',    }, options);}复制代码

参数默认值

// Badfunction App(name) {    name = name || 'App';    // ...}// Goodfunction App(name = 'App') {    // ...}复制代码

函数式风格

// Badfunction querify(object = {}) {    const keys = Object.keys(object);    let result = '';    for(let i = 0; i < keys.length; i++) {        result += `&${keys[i]}=${object[keys[i]]}`;    }    result = result.slice(1);    return result;}// Goodfunction querify(object = {}) {    const keys = Object.keys(object);    const result = keys.reduce((prev, current) => {        prev += `&${current}=${object[current]}`;        return prev;    }, '').slice(1);    return result;}复制代码

避免使用 switch

// Badfunction reducer(state = 0, {type}) {    switch (type) {        case 'INCREASE':            return state + 1;        case 'DECREASE':            return state - 1;        default:            return state;    }}// Goodfunction reducer(state = 0, {type}) {    const mapping = {        'INCREASE': state + 1,        'DECREASE': state - 1,    };    const effective = Object.keys(mapping).includes(type);    return effective ? mapping[type] : state;}复制代码

封装 if 判断条件

下面是笔者写的 的 PostCSS 插件中的 :

// Badif (/background[^:]*.*url[^;]+/gi.test(ruleString)) {    const [originURL, URL] = getImageURL(ruleString);    // ...}// Goodconst hasBackground = rule => /background[^:]*.*url[^;]+/gi.test(rule);if (hasBackground(ruleString)) {    const [originURL, URL] = getImageURL(ruleString);    // ...}复制代码

只做一件事

函数是最小可复用单元,所以如果一个函数做了多个事情的话,代表这个函数难以被复用,So, just do one thing.

// Badfunction notify(users) {    users.map(user => {        const record = DB.find(user);        if (record.isActive()) {            sendMessage(user);        }    });}// Good// judge activation onlyfunction isActive(user) {    const record = DB.find(user);    return record.isActive();}function notify(users) {    users.filter(isActive).forEach(sendMessage);}复制代码

不用「否定」语法命名函数

// Badconst isNotSupport = () => {};const canNotUpdate = () => {};// Goodconst isSupport = () => {};const canUpdate = () => {};复制代码

使用 ES6+ 语法

解构

// Badconst first = items[0];const second = items[1];const name = me.name;const age = me.age;// Goodconst [first, second] = items;const { name, age } = me;// Badfunction App(options) {    track({        name: options.name,        version: options.version,        env: options.env,    });}// Good// 解构函数参数function App({name, version, env}) {    track({        name: name,        version: version,        env: env,    });}// Bestfunction App({name, version, env}) {    // 使用对象简写    track({ name, version, env });}复制代码

模板字符串

// Badconst greeting = name => 'Hello ' + name + '!';// Goodconst greeting = name => `Hello ${name}!`;复制代码

箭头函数

// Badfunction greeting(name) {    return `Hello ${name}!`;}// Goodconst greeting = name => `Hello ${name}!`;复制代码

弃用回调函数

// BadfetchCurrentUser((error, currentUser) => {    if(error) throw Error;    fetchArticles(currentUser.id, (error, articles) => {        if(error) throw Error;        // articles here...    });});// GoodfetchCurrentUser.then(currentUser => currentUser.id).then(fetchArticles).then(articles => {    // articles here...}).catch(() => {    throw Error;});// Besttry {    const currentUser = await fetchCurrentUser();    const articles = await fetchArticles(currentUser.id);    // articles here...} catch() {    throw Error;}复制代码

总结

长而具有描述性的名称,要比短而令人费解的名称好,也比描述性的长注释更好,好的代码是 自注释 的,不要担心变量名太长(打包工具压缩后都一样)。

代码不只是写给机器看的,也是写给人看的,所以从现在开始编写 可读性强易维护 的代码吧。

最后友情提醒大家 代码千万行,注释第一行。编程不规范,同事两行泪。

更多干货请关注公众号「前端小专栏:QianDuanXiaoZhuanLan」

转载于:https://juejin.im/post/5caae923f265da24d70c395a

你可能感兴趣的文章
GridView绑定数据后想要更换每个单元格中内容的方法
查看>>
python Tkinter 全屏显示
查看>>
导航栏固定在顶部,滑动下面内容,不同的内容块,上面的导航相应的变颜色...
查看>>
java反射:加载成员方法
查看>>
165. Compare Version Numbers
查看>>
Uva 11384 正整数序列
查看>>
select2插件
查看>>
软件测试管理工具实践任务内容与要求
查看>>
基于Ubuntu 12.04的Android内核源码下载介绍
查看>>
iOS - 直播总结(理论到实践)
查看>>
spring boot thymeleaf
查看>>
2015.02 零碎知识点
查看>>
《FPGA全程进阶---实战演练》第三章之PCB设计之去耦电容
查看>>
FLASH的知识【转】
查看>>
如何在Ubuntu 16.04安装的Git【转】
查看>>
十个你需要在 PHP 7 中避免的坑
查看>>
随机森林(分类与回归)
查看>>
实现多态的方法二 ——抽象类
查看>>
我做YunOS,招来了很多非议,甚至比我这一辈子挨的骂还多,但我不后悔。在中国,想做移动操作系统的公司不少,许多比我们更有条件,最后顽强地坚持下来并且真正占有市场份额的只有我们。...
查看>>
os x 10.11 中 root用户无法删除 /usr/bin/ 目录下的程序
查看>>