看看这些被同事喷的JS代码风格你写过多少

2024-03-16 04:18
文章标签 代码 js 风格 看看 同事

本文主要是介绍看看这些被同事喷的JS代码风格你写过多少,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

640?wx_fmt=jpeg

一、变量相关

(1)变量数量的定义

NO:滥用变量:

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;	
}

YES: 数据只使用一次或不使用就无需装到变量中

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

(2)变量的命名

NO:自我感觉良好的缩写

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

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

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

(3)特定的变量

NO:无说明的参数

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

YES:添加变量

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

(4)变量的命名

NO:命名过于啰嗦

let nameString;	
let theUsers;

YES: 做到简洁明了

let name;	
let users;

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

NO:长代码不知道啥意思

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)避免使用太多的全局变量

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

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

YES:少用或使用替代方案 你可以选择只用局部变量。通过(){}的方法。

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

(7) 变量的赋值。

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

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

YES:对于求值变量,做好兜底。

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'; // 因为有底了,所以不要兜着。

二、函数相关

(1)函数命名

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

function showFriendsList() {....} // 现在问,你知道这个返回的是一个数组,还是一个对象,还是true or false。你能答的上来否?你能答得上来我请你吃松鹤楼的满汉全席还请你不要当真。

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

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

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

NO: 不要让功能函数的输出变化无常。

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

YES:功能函数使用纯函数,输入一致,输出结果永远唯一

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

(3)函数传参

NO:传参无说明

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

YES: 传参有说明

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

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

NO: 无法辨别函数意图

function emlU(user) {	....	
}

YES:动词开头,函数意图就很明显

function sendEmailToUser(user) {	....	
}

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

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

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

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

YES: 功能拆解,

function sendEmailToActiveClients(clients) {  //各个击破,易于维护和复用	clients.filter(isActiveClient).forEach(email)	
}	
function isActiveClient(client) {	const clientRecord = database.lookup(client)	return clientRecord.isActive()	
}

(6)优先使用函数式编程

NO: 使用for循环编程

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

YES:使用函数式编程

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

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

No: if else过多

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

YES: 可以使用switch替代或用数组替代

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

三、尽量使用ES6,有可以能的话ES7中新语法(只罗列最常用的新语法,说实话,有些新语法不怎么常用)

(1)尽量使用箭头函数

NO:采用传统函数

function foo() {	// code	
}

YES:使用箭头函数

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

(2)连接字符串

NO:采用传统+号

var message = 'Hello ' + name + ', it's ' + time + ' now'

YES:采用模板字符

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

(3) 使用解构赋值

NO:使用传统赋值:

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];

YES:使用结构赋值:

const data = {name:'dys', age:1};	
const {name, age} = data;   // 怎么样,是不是简单明了	
var fullName = ['jackie', 'willen'];	
const [firstName, lastName] = fullName;

(4) 尽量使用类class

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

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

YES:采用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() {	/* ... */	}	
}

先写到这了,这是目前为止发现的问题,这篇文章中并没有完全覆盖到常见的写代码的不好的习惯,所以你如果觉的有需要补充的,都可以在文章下方评论,或者直接到我的Github的这篇文章中评论。对于有用的,都将补充到我的掘金和Github中去。同时,你如果觉的文章写得还可以,Please在我的Github中送上你宝贵的Star,你的Star是我继续写文章最大的动力。

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

参考资料

https://blog.risingstack.com/javascript-clean-coding-best-practices-node-js-at-scale/(JavaScript Clean Coding Best Practices)

https://www.zhihu.com/question/20635785 (如何写出优美的 JavaScript 代码?)

END

作者:殷荣桧

这篇关于看看这些被同事喷的JS代码风格你写过多少的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/814274

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1