那些年被吐槽的JavaScript代码风格你写过多少?老师傅来打通你的任督二脉!

现在写代码比以前好多了,代码的格式都有 eslint、prettier、babel(写新版语法) 这些来保证,然而,技术手段再高端都不能解决代码可读性(代码能否被未来的自己和同事看懂)的问题,因为这个问题只有人自己才能解决。我们写代码要写到下图中左边这样基本上就功德圆满了。

(1)变量数量的定义

拒绝:滥用变量

let kpi = 4;  // 定义好了之后再也没用过
function example() {
    var a = 1;
    var b = 2;
    var c = a+b;
    var d = c+1;
    var e = d+a;
    return e;
}

正确姿势:: 数据只使用一次或不使用就无需装到变量中

let kpi = 4;  // 没用的就删除掉,不然过三个月自己都不敢删,怕是不是那用到了
function example() {
    var a = 1;
    var b = 2;
    return 2a+b+1;
}

(2) 变量的命名

拒绝:自我感觉良好的缩写

let fName = ‘jackie‘; // 看起来命名挺规范,缩写,驼峰法都用上,ESlint 各种检测规范的工具都通过,But,fName 是啥?这时候,你是不是想说 What are you 弄啥呢?
let lName = ‘willen‘; // 这个问题和上面的一样

正确姿势:无需对每个变量都写注释,从名字上就看懂

let firstName = ‘jackie‘; // 怎么样,是不是一目了然。少被喷了一次
 let lastName = ‘willen‘;

(3) 特定的变量

拒绝:无说明的参数

if (value.length < 8) { // 为什么要小于 8,8 表示啥?长度,还是位移,还是高度?Oh,my God!!
    ....
}

正确姿势:添加变量

const MAX_INPUT_LENGTH = 8;
if (value.length < MAX_INPUT_LENGTH) { // 一目了然,不能超过最大输入长度
    ....
}

(4)变量的命名

拒绝:命名过于啰嗦

let nameString;
let theUsers;

YES: 做到简洁明了

let name;
let users;

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

正确姿势:长代码不知道啥意思

const address = ‘One Infinite Loop, Cupertino 95014‘;
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(
  address.match(cityZipCodeRegex)[1], // 这个公式到底要干嘛,对不起,原作者已经离职了。自己看代码
  address.match(cityZipCodeRegex)[2], // 这个公式到底要干嘛,对不起,原作者已经离职了。自己看代码
);

YES:用变量名来解释长代码的含义

const address = ‘One Infinite Loop, Cupertino 95014‘;
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
const [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode);

(6)避免使用太多的全局变量

拒绝:在不同的文件不停的定义全局变量

name.js
window.name = ‘a‘;
hello.js
window.name = ‘b‘;
time.js
window.name = ‘c‘;  // 三个文件的先后加载顺序不同,都会使得 window.name 的值不同,同时,你对 window.name 的修改了都有可能不生效,因为你不知道你修改过之后别人是不是又在别的说明文件中对其的值重置了。所以随着文件的增多,会导致一团乱麻。

正确姿势:少用或使用替代方案

你可以选择只用局部变量。通过 (){}的方法。

如果你确实用很多的全局变量需要共享,你可以使用 vuex,redux 或者你自己参考 flux 模式写一个也行。

(7) 变量的赋值

拒绝:对于求值获取的变量,没有兜底。

const MIN_NAME_LENGTH = 8;
let lastName = fullName[1];
if(lastName.length > MIN_NAME_LENGTH) { // 这样你就给你的代码成功的埋了一个坑,你有考虑过如果 fullName = [‘jackie‘] 这样的情况吗?这样程序一跑起来就爆炸。要不你试试。
    ....
}

正确姿势:对于求值变量,做好兜底。

const MIN_NAME_LENGTH = 8;
let lastName = fullName[1] || ‘‘; // 做好兜底,fullName[1] 中取不到的时候,不至于赋值个 undefined, 至少还有个空字符,从根本上讲,lastName 的变量类型还是 String,String 原型链上的特性都能使用,不会报错。不会变成 undefined。
if(lastName.length > MIN_NAME_LENGTH) {
    ....
}
其实在项目中有很多求值变量,对于每个求值变量都需要做好兜底。
let propertyValue = Object.attr || 0; // 因为 Object.attr 有可能为空,所以需要兜底。
但是,赋值变量就不需要兜底了。
let a = 2; // 因为有底了,所以不要兜着。
let myName = ‘Tiny‘; // 因为有底了,所以不要兜着。

这里推荐一下我的前端学习交流群:731771211,里面都是学习前端的,如果你想制作酷炫的网页,想学习编程。从最基础的HTML+CSS+JS【炫酷特效,游戏,插件封装,设计模式】到移动端HTML5的项目实战的学习资料都有整理,送给每一位前端小伙伴,有想学习web前端的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入。

点击:加入

二、函数相关

(1)函数命名

拒绝:从命名无法知道返回值类型

function showFriendsList() {....} // 现在问,你知道这个返回的是一个数组,还是一个对象,还是 true or false。你能答的上来否?

正确姿势:对于返回 true or false 的函数,最好以 should/is/can/has 开头

function shouldShowFriendsList() {...}
function isEmpty() {...}
function canCreateDocuments() {...}
function hasLicense() {...}

(2) 功能函数最好为纯函数

拒绝: 不要让功能函数的输出变化无常

function plusAbc(a, b, c) {  // 这个函数的输出将变化无常,因为 api 返回的值一旦改变,同样输入函数的 a,b,c 的值,但函数返回的结果却不一定相同。
        var c = fetch(‘../api‘);
        return a+b+c;
}

正确姿势:功能函数使用纯函数,输入一致,输出结果永远唯一

function plusAbc(a, b, c) {  // 同样输入函数的 a,b,c 的值,但函数返回的结果永远相同。
        return a+b+c;
}

(3)函数传参

拒绝:传参无说明

page.getSVG(api, true, false); // true 和 false 啥意思,一目不了然

正确姿势: 传参有说明

page.getSVG({
    imageApi: api,
    includePageBackground: true, // 一目了然,知道这些 true 和 false 是啥意思
    compress: false,
})

(4)动作函数要以动词开头

拒绝: 无法辨别函数意图

function emlU(user) {
    ....
}

正确姿势:动词开头,函数意图就很明显

function sendEmailToUser(user) {
    ....
}

(5)一个函数完成一个独立的功能,不要一个函数混杂多个功能

这是软件工程中最重要的一条规则,当函数需要做更多的事情时,它们将会更难进行编写、测试、理解和组合。当你能将一个函数抽离出只完成一个动作,他们将能够很容易的进行重构并且你的代码将会更容易阅读。如果你严格遵守本条规则,你将会领先于许多开发者。

拒绝:函数功能混乱,一个函数包含多个功能。最后就像能以一当百的老师傅一样,被乱拳打死(乱拳(功能复杂函数)打死老师傅(老程序员))

function sendEmailToClients(clients) {
  clients.forEach(client => {
    const clientRecord = database.lookup(client)
    if (clientRecord.isActive()) {
      email(client)
    }
  })
}

正确姿势: 功能拆解

function sendEmailToActiveClients(clients) {  // 各个击破,易于维护和复用
  clients.filter(isActiveClient).forEach(email)
}

function isActiveClient(client) {
  const clientRecord = database.lookup(client)
  return clientRecord.isActive()
}

(6)优先使用命令式编程

拒绝: 使用 for 循环编程

for(i = 1; i <= 10; i++) { // 一看到 for 循环让人顿生不想看的情愫
   a[i] = a[i] +1;
}

正确姿势:使用命令式编程

let b = a.map(item => ++item) // 怎么样,是不是很好理解,就是把 a 的值每项加一赋值给 b 就可以了。现在在 javascript 中几乎所有的 for 循环都可以被 map,filter,find,some,any,forEach 等命令式编成取代。

(7) 函数中过多的采用 if else ..

拒绝: if else 过多

if (a === 1) {
    ...
} else if (a ===2) {
    ...
} else if (a === 3) {
    ...
} else {
   ...
}

正确姿势: 可以使用 switch 替代或用数组替代

switch(a) {
   case 1:
           ....
   case 2:
           ....
   case 3:
           ....
  default:
       ....
}
Or
let handler = {
    1: () => {....},
    2: () => {....}.
    3: () => {....},
    default: () => {....}
}

handler[a]() || handler[‘default‘]()

尽量使用 ES6

(1)尽量使用箭头函数

拒绝:采用传统函数

function foo() {
  // code
}

正确姿势:使用箭头函数

let foo = () => {
  // code
}

(2)连接字符串

拒绝:采用传统 + 号

var message = ‘Hello ‘ + name + ‘, it\‘s ‘ + time + ‘ now‘

正确姿势:采用模板字符

var message = `Hello ${name}, it‘s ${time} now`

(3) 使用解构赋值

拒绝:使用传统赋值

var data = { name: ‘dys‘, age: 1 };
var name = data.name;
var age = data.age;

var fullName = [‘jackie‘, ‘willen‘];
var firstName = fullName[0];
var lastName = fullName[1];

正确姿势:使用结构赋值

const data = {name:‘dys‘, age:1};
const {name, age} = data;   // 怎么样,是不是简单明了

var fullName = [‘jackie‘, ‘willen‘];
const [firstName, lastName] = fullName;

(4)尽量使用类 class

拒绝: 采用传统的函数原型链实现继承

典型的 ES5 的类 (function) 在继承、构造和方法定义方面可读性较差,当需要继承时,优先选用 class。代码太多,就省略了。

正确姿势:采用 ES6 类实现继承

class Animal {
  constructor(age) {
    this.age = age
  }

  move() {
    /* ... */
  }
}

class Mammal extends Animal {
  constructor(age, furColor) {
    super(age)
    this.furColor = furColor
  }

  liveBirth() {
    /* ... */
  }
}

class Human extends Mammal {
  constructor(age, furColor, languageSpoken) {
    super(age, furColor)
    this.languageSpoken = languageSpoken
  }

  speak() {
    /* ... */
  }
}

注:除了上述这些人为习惯之外,就像前面提到的,对于机械性的,你可以使用 Babel、Eslint、Prettier 这些工具来保证代码的格式一致。

有句话叫做“方法不对,努力白费”所有的前端大神都有自己的学习方法,而学web前端的学习也基本一致,而对于一个什么都不懂的初学者,根本不会知道该怎么学,这也是造成失败的最直接原因。所以学web前端一定要有人指点。如果你处在迷茫期,找不到方向。可以加入我们的前端学习交流qun:731771211 。有任何不明白的东西随时来问我。

点击:加入

原文地址:http://blog.51cto.com/14138686/2340377

时间: 2024-10-08 07:13:24

那些年被吐槽的JavaScript代码风格你写过多少?老师傅来打通你的任督二脉!的相关文章

世界顶级互联网公司 Google JavaScript 代码风格指南

Google 和 Airbnb 是目前最流行的 JavaScript 代码风格,如果你长期使用 JavaScript 来写代码的话,建议对比看看. 以下是我认为在 Google 代码风格指南中最有意思的十三条规则,和大家分享一下: 使用空格,而不是 tab 除了行终止符外,在系统文件中,空格是唯一表示空白的字符,这意味着 tab 不能作为缩进使用. 这份指南规定用2个空格(而不是4个)来表示缩进. // bad function foo() { ????let name; } // bad fu

JavaScript 代码风格---Vue.js风格指南

Vue.js风格指南 https://cn.vuejs.org/v2/style-guide/ 还有google和airbnb的js代码风格 原文地址:https://www.cnblogs.com/jane-panyiyun/p/12289354.html

JavaScript 代码风格指南

一.基本格式 缩进 建议每级4个空格,可以给编辑器设置tab = 4个空格,自动转换 分号 不要省略分号,防止ASI(自动插入分号)错误 行宽 每行代码不超过80个字符,过长应该用操作符手动断行 断行 操作符在上一行末尾,且下一行缩进2级,如果是赋值语句,还应该和等号后面部分对齐 空行 函数声明与函数声明.变量声明与函数声明.函数内部的逻辑块之间都应该有空行隔开 作者尼古拉斯还建议在流程控制块顶部留一个空行,但给的例子不是很明确 命名 变量名/函数名:Camel(驼峰)规则,首词首字母小写,后续

10段代码打通js学习的任督二脉

前言 为了Node.js做准备,js的基本功还是很重要的.所以正值1024程序员节的时候所以找了些题目,整理了一下知识点. 简单回调 代码 function foo(){ console.log(this.a); } function doFoo(fn){ fn(); } function doFoo2(o){ o.foo(); } var obj = { a: 2, foo: foo }; var a = "I'm an a"; doFoo(obj.foo); doFoo2(obj)

JavaScript编码风格

最近在看前端大牛Nicbolas C.Zakas的<编写可维护的JavaScript代码>一书.觉得里面的很多知识点都写的很好,所以,就写篇博文,总结一下吧!编码规范对于程序设计来说是很重要的,因为如果编码风格不一致的话,代码看上去就会很乱,是很难维护的.当然,不同的开发团队有着不同的编码规范,比较著名的有,Google编码规范,jQuery编码规范,dojo编码规范以及Yahoo!编码规范,等等. 第一,Indentation Levels(缩进).目前比较流行的是2空格缩进和4空格缩进,比

.net 代码风格规范

声明:内容非原创,转自张子阳博客. 对于为什么是转载,唯一原因就是这东西居然比我整理的好,直接用得了. 1. C# 代码风格要求 1.1注释 类型.属性.事件.方法.方法参数,根据需要添加注释. 如果类型.属性.事件.方法.方法参数的名称已经是自解释了,则不需要加注释:否则必须添加注释. 当添加注释时,添加方式如下图所示: 1.2 类型(类.结构.委托.接口).字段.属性.方法.事件的命名 优先考虑英文,如果英文没有合适的单词描述,可以使用拼音,使用中文是不符合要求的. 唯一可以使用中文的地方是

.NET之美——.Net 项目代码风格要求

.Net 项目代码风格要求 PDF版下载:项目代码风格要求V1.0.pdf 代码风格没有正确与否,重要的是整齐划一,这是我拟的一份<.Net 项目代码风格要求>,供大家参考. 1. C# 代码风格要求 1.1注释 类型.属性.事件.方法.方法参数,根据需要添加注释. 如果类型.属性.事件.方法.方法参数的名称已经是自解释了,不需要加注释:否则需要添加注释. 当添加注释时,添加方式如下图所示: 1.2 类型(类.结构.委托.接口).字段.属性.方法.事件的命名 优先考虑英文,如果英文没有合适的单

Javascript代码规范

1. 前言 JavaScript一直有着广泛的应用,特别是在浏览器端的行为管理.本文档的目标是使JavaScript代码风格保持一致,容易被理解和被维护. 虽然本文档是针对JavaScript设计的,但是在使用各种JavaScript的预编译语言时(如TypeScript等)时,适用的部分也应尽量遵循本文档的约定. 任何问题或建议,欢迎跟我们讨论 2. 代码风格 2.1. 文件 ·[建议] JavaScript 文件使用无 BOM 的 UTF-8 编码. 解释 UTF-8 编码具有更广泛的适应性

项目代码风格要求

1. C# 代码风格要求 1.1注释 类型.属性.事件.方法.方法参数,根据需要添加注释. 如果类型.属性.事件.方法.方法参数的名称已经是自解释了,则不需要加注释:否则必须添加注释. 当添加注释时,添加方式如下图所示: 1.2 类型(类.结构.委托.接口).字段.属性.方法.事件的命名 优先考虑英文,如果英文没有合适的单词描述,可以使用拼音,使用中文是不符合要求的. 唯一可以使用中文的地方是枚举的枚举项,枚举项实际已经不属于本节标题的范畴了.这里只是放到一起说明,如下图所示: 1.3 不使用缩