Автор: Инь Жунхуэй@Tencent
содержание:
1. Переменная корреляция
2. Функция, связанная
3. Попробуйте использовать ES6, если возможно, новый синтаксис в ES7
Писать код сейчас намного лучше, чем раньше.Формат кода гарантируется eslint,prettier,babel (написание новой версии грамматики).Однако, какими бы техническими средствами ни были совершенны, читабельность кода не решается (может ли код быть использован будущим я и коллеги) понять) проблема, потому что эта проблема может быть решена только самим человеком. Когда мы пишем код, нам нужно написать его в левой части рисунка ниже, что в основном завершает достоинства.
Примечание. Из-за личного уровня и видения эта статья не полностью охватывает распространенные вредные привычки написания кода, поэтому, если вы чувствуете, что вам нужно что-то добавить, вы можете оставить комментарий под статьей или напрямую мнеGithubКомментарии в этой статье. Для полезных, добавлю к моим наггетсам иGithubиди в. В то же время, если вы считаете, что статья в порядке, пожалуйста, разместите ее в моемGithubПришлите свою драгоценную Звезду, ваша Звезда - самая большая мотивация для меня продолжать писать статьи.
1. Переменная корреляция
(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 2*a+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;
ДА: Будьте кратки и ясны
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], // 这个公式到底要干嘛,对不起,原作者已经离职了。自己看代码
);
ДА: используйте имена переменных, чтобы объяснить значение длинного кода
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'; // 因为有底了,所以不要兜着。
2. Функция, связанная
(1) Именование функцийНЕТ: Тип возвращаемого значения не может быть известен из именования
function showFriendsList() {....} // 现在问,你知道这个返回的是一个数组,还是一个对象,还是true or false。你能答的上来否?你能答得上来我请你吃松鹤楼的满汉全席还请你不要当真。
Да: Для функций, которые возвращают TRUE или FALSE, лучше начать с должно / есть / может / есть
function shouldShowFriendsList() {...}
function isEmpty() {...}
function canCreateDocuments() {...}
function hasLicense() {...}
(2) Функция функции лучше всего для чистой функции.
NO: Не делайте вывод функции function непостоянным.
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(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 (a === 1) {
...
} else if (a ===2) {
...
} else if (a === 3) {
...
} else {
...
}
ДА: вместо этого можно использовать переключатель или вместо этого можно использовать массив
switch(a) {
case 1:
....
case 2:
....
case 3:
....
default:
....
}
Or
let handler = {
1: () => {....},
2: () => {....}.
3: () => {....},
default: () => {....}
}
handler[a]() || handler['default']()
3. Попробуйте использовать ES6, если есть возможность, новый синтаксис в ES7 (перечислен только самый часто используемый новый синтаксис, если честно, какой-то новый синтаксис используется не очень часто)
(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() {
/* ... */
}
}
Я написал это первым. Это проблема, которую я обнаружил до сих пор. Эта статья не полностью охватывает распространенные вредные привычки написания кода, поэтому, если вы чувствуете, что вам нужно что-то добавить, вы можете прокомментировать ниже статьи или непосредственно в мойGithubкомментарии в этой статье. За полезное, добавлю в свои наггетсы иGithubиди в. В то же время, если вы считаете, что статья в порядке, пожалуйста, разместите ее в моемGithubПришлите свою драгоценную Звезду, ваша Звезда - самая большая мотивация для меня продолжать писать статьи.
注:除了上述这些人为习惯之外,就像前面提到的,对于机械性的,你可以使用Babel、Eslint、Prettier这些工具来保证代码的格式一致。
использованная литература
blog.risingstack.com/JavaScript-…(Рекомендации по чистому кодированию JavaScript)
Ууху. Call.com/question/20…(Как написать красивый код JavaScript?)