Добавить Автора Переводчик: Front-end Xiaozhi Источник: гитхаб
Ставьте лайк и смотрите снова, формируйте привычку
эта статья
GitHub
GitHub.com/QQ449245884…Он был включен в вышеизложенное, и более ранние статьи с высокими похвалами были классифицированы, а также было систематизировано множество моих документов и учебных материалов. Добро пожаловать в Star and Perfect. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Надеюсь, у нас что-то получится вместе.
В разработке имена переменных и функций, как правило, должны быть четкими и понятными.Постарайтесь посмотреть на имена, чтобы люди знали о ваших намерениях.Поэтому очень важны имена переменных и функций и имена функций.
Переменная
Используйте осмысленные и произносимые имена переменных
// 不好的写法
const yyyymmdstr = moment().format("YYYY/MM/DD");
// 好的写法
const currentDate = moment().format("YYYY/MM/DD");
использовать один и тот же словарь для переменных одного типа
// 不好的写法
getUserInfo();
getClientData();
getCustomerRecord();
// 好的写法
getUser();
Используйте поисковые имена
Мы читаем гораздо больше, чем пишем, поэтому слишком произвольные имена не только затруднят последующее сопровождение, но и навредят разработчикам, читающим наш код. Сделайте ваши имена переменных читабельными, напримерbuddy.js
а такжеESLint
Такие инструменты могут помочь идентифицировать безымянные константы.
// 不好的写法
// 86400000 的用途是什么?
setTimeout(blastOff, 86400000);
// 好的写法
const MILLISECONDS_IN_A_DAY = 86_400_000;
setTimeout(blastOff, MILLISECONDS_IN_A_DAY);
Используйте объясняющие переменные
// 不好的写法
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);
Избегайте головокружительных догадок
явный для неявного
// 不好的写法
const locations = ["Austin", "New York", "San Francisco"];
locations.forEach(l => {
doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
// 等等,“l”又是什么?
dispatch(l);
// 好的写法
const locations = ["Austin", "New York", "San Francisco"];
locations.forEach(location => {
doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
dispatch(location);
});
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Не нужно добавлять ненужный контекст
Если имя класса / имя объекта уже указано, нет необходимости повторять его в имени переменной.
// 不好的写法
const Car = {
carMake: "Honda",
carModel: "Accord",
carColor: "Blue"
};
function paintCar(car) {
car.carColor = "Red";
}
// 好的写法
const Car = {
make: "Honda",
model: "Accord",
color: "Blue"
};
function paintCar(car) {
car.color = "Red";
}
Используйте аргументы по умолчанию вместо логических операций ИЛИ (И).
// 不好的写法
function createMicrobrewery(name) {
const breweryName = name || "Hipster Brew Co.";
// ...
}
// 好的写法
function createMicrobrewery(name = "Hipster Brew Co.") {
// ...
}
функция
аргументы функции (в идеале 2 или меньше)
Ограничение числа аргументов функции важно, потому что это упрощает тестирование функций. С более чем тремя параметрами результаты комбинаторного взрыва и большое количество различных ситуаций должны быть протестированы с каждым отдельным параметром.
Один или два аргумента идеальны, а трех следует по возможности избегать. Кроме того, он должен быть объединен. В большинстве случаев более трех параметров могут быть заменены объектами.
// 不好的写法
function createMenu(title, body, buttonText, cancellable) {
// ...
}
createMenu("Foo", "Bar", "Baz", true);
// 好的写法
function createMenu({ title, body, buttonText, cancellable }) {
// ...
}
createMenu({
title: "Foo",
body: "Bar",
buttonText: "Baz",
cancellable: true
});
Функции должны делать только одну вещь
Это, безусловно, самое важное правило в разработке программного обеспечения. Когда функции выполняют несколько функций, их сложнее составить, протестировать и обосновать. Когда функцию можно выделить в операцию, ее можно легко реорганизовать, и код будет читаться более четко.
// 不好的写法
function emailClients(clients) {
clients.forEach(client => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}
// 好的写法
function emailActiveClients(clients) {
clients.filter(isActiveClient).forEach(email);
}
function isActiveClient(client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive();
}
Имя функции должно описывать, что она делает
// 不好的写法
function addToDate(date, month) {
// ...
}
const date = new Date();
// 从函数名称很难知道添加什么
addToDate(date, 1);
// 好的写法
function addMonthToDate(month, date) {
// ...
}
const date = new Date();
addMonthToDate(1, date);
Функции должны иметь только один уровень абстракции
Когда существует более одной функции уровня абстракции, это означает, что функция делает слишком много, и функцию необходимо разделить для повторного использования и более простого тестирования.
// 不好的写法
function parseBetterJSAlternative(code) {
const REGEXES = [
// ...
];
const statements = code.split(" ");
const tokens = [];
REGEXES.forEach(REGEX => {
statements.forEach(statement => {
// ...
});
});
const ast = [];
tokens.forEach(token => {
// lex...
});
ast.forEach(node => {
// parse...
});
}
// 好的写法
function parseBetterJSAlternative(code) {
const tokens = tokenize(code);
const syntaxTree = parse(tokens);
syntaxTree.forEach(node => {
// parse...
});
}
function tokenize(code) {
const REGEXES = [
// ...
];
const statements = code.split(" ");
const tokens = [];
REGEXES.forEach(REGEX => {
statements.forEach(statement => {
tokens.push(/* ... */);
});
});
return tokens;
}
function parse(tokens) {
const syntaxTree = [];
tokens.forEach(token => {
syntaxTree.push(/* ... */);
});
return syntaxTree;
}
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
удалить повторяющийся код
Старайтесь избегать дублирования кода, дублирование кода — это плохо, это означает, что если нам нужно изменить какую-то логику, мы должны изменить много мест.
Часто дублирующийся код возникает из-за того, что есть две или более слегка отличающихся друг от друга вещи, которые имеют много общего, но различия между ними вынуждают нас писать две или более независимых функции, которые делают много одинаковых вещей. Удаление повторяющегося кода означает создание абстракции, которая может обрабатывать этот другой набор вещей с помощью всего одной функции/модуля/класса.
Правильная абстракция имеет решающее значение, поэтому мы должны следовать классам, перечисленным в разделеТВЕРДЫЕ принципы. Плохие абстракции могут быть хуже, чем дублированный код, так что будьте осторожны! Сказав все это, если вы можете сделать хорошую абстракцию, сделайте это! вещь, вам нужно обновить несколько мест.
Шесть принципов конструктивных узоров являются:
- Принцип единой ответственности: Принцип единой ответственности
- Открытый закрытый принцип: Открытый закрытый принцип
- Принцип подстановки Лисков: Принцип подстановки Лисков
- Закон Деметры: Закон Деметры
- Принцип разделения интерфейса: Принцип разделения интерфейса
- Принцип инверсии зависимости: Принцип инверсии зависимости
Сочетание начальных букв этих шести принципов (две L считаются как один) означает SOLID (твердый, стабильный), что представляет собой преимущества использования этих шести принципов в сочетании: для создания стабильных, гибких и надежных конструкций. Давайте рассмотрим эти шесть принципов дизайна по отдельности.
неправильное написание
function showDeveloperList(developers) {
developers.forEach(developer => {
const expectedSalary = developer.calculateExpectedSalary();
const experience = developer.getExperience();
const githubLink = developer.getGithubLink();
const data = {
expectedSalary,
experience,
githubLink
};
render(data);
});
}
function showManagerList(managers) {
managers.forEach(manager => {
const expectedSalary = manager.calculateExpectedSalary();
const experience = manager.getExperience();
const portfolio = manager.getMBAProjects();
const data = {
expectedSalary,
experience,
portfolio
};
render(data);
});
}
хорошее письмо
function showEmployeeList(employees) {
employees.forEach(employee => {
const expectedSalary = employee.calculateExpectedSalary();
const experience = employee.getExperience();
const data = {
expectedSalary,
experience
};
switch (employee.type) {
case "manager":
data.portfolio = employee.getMBAProjects();
break;
case "developer":
data.githubLink = employee.getGithubLink();
break;
}
render(data);
});
}
использоватьObject.assign
установить объект по умолчанию
неправильное написание
const menuConfig = {
title: null,
body: "Bar",
buttonText: null,
cancellable: true
};
function createMenu(config) {
config.title = config.title || "Foo";
config.body = config.body || "Bar";
config.buttonText = config.buttonText || "Baz";
config.cancellable =
config.cancellable !== undefined ? config.cancellable : true;
}
createMenu(menuConfig);
хорошее письмо
const menuConfig = {
title: "Order",
// User did not include 'body' key
buttonText: "Send",
cancellable: true
};
function createMenu(config) {
config = Object.assign(
{
title: "Foo",
body: "Bar",
buttonText: "Baz",
cancellable: true
},
config
);
// config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
// ...
}
createMenu(menuConfig);
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Не используйте флаги в качестве аргументов функции
Флаг сообщает потребителю, что эта функция может делать несколько вещей и что функция должна делать одну. Если функции следуют разным логическим путям кода, разделите их.
// 不好的写法
function createFile(name, temp) {
if (temp) {
fs.create(`./temp/${name}`);
} else {
fs.create(name);
}
}
// 好的写法
function createFile(name) {
fs.create(name);
}
function createTempFile(name) {
createFile(`./temp/${name}`);
}
Как избежать побочных эффектов (часть 1)
Побочные эффекты возникают, когда функция ничего не делает, кроме как принимает значение и возвращает другое значение или значения. Побочными эффектами могут быть запись в файл, изменение какой-либо глобальной переменной или случайная отправка всех ваших средств незнакомцу.
неправильное написание
let name = "Ryan McDermott";
function splitIntoFirstAndLastName() {
name = name.split(" ");
}
splitIntoFirstAndLastName();
console.log(name); // ['Ryan', 'McDermott'];
хорошее письмо
function splitIntoFirstAndLastName(name) {
return name.split(" ");
}
const name = "Ryan McDermott";
const newName = splitIntoFirstAndLastName(name);
console.log(name); // 'Ryan McDermott';
console.log(newName); // ['Ryan', 'McDermott'];
Как избежать побочных эффектов (часть вторая)
существуетJavaScript
, примитивные значения передаются по значению, а объекты/массивы передаются по ссылке. Для объектов и массивов, если есть функция, которая вносит изменения в массив корзины (например, добавляя товар для покупки), это добавление затронет любые другие функции, использующие этот массив корзины. Это может быть здорово, но может быть и плохо. Представим неприятную ситуацию:
Пользователь нажимает кнопку «Купить», которая вызываетpurchase
функция, которая затем делает сетевой запрос и отправляетcart
Массив отправляется на сервер. Из-за плохого интернет-соединения,purchase
Функция должна продолжать повторять запрос. А что, если перед запуском сетевого запроса пользователь случайно нажмет кнопку "Добавить в корзину" на товаре, который ему на самом деле не нужен? Если это произойдет, и начнется сетевой запрос, функция покупки отправит товар, который был добавлен случайно, потому что он имеет ссылку на массив корзины,addItemToCart
Функция изменяет этот массив корзин, добавляя.
Хорошее решение этоaddItemToCart
всегда клонироватьcart
array, отредактируйте его и вернитесь к clone. Это гарантирует, что никакие изменения не повлияют на другие функции, на которые ссылается корзина.
В отношении этого подхода следует отметить две вещи:
1. В некоторых случаях нам действительно нужно изменить входной объект, но когда мы примем эту практику программирования, мы обнаружим, что это очень редко, и большинство вещей можно изменить без побочных эффектов.
2. С точки зрения производительности, клонирование крупных объектов может быть очень дорогим. К счастью, на практике это не большая проблема, потому что есть многоотличная библиотекаДелает этот метод программирования быстрым и менее требовательным к памяти, чем ручное клонирование объектов и массивов.
// 不好的写法
const addItemToCart = (cart, item) => {
cart.push({ item, date: Date.now() });
};
// 好的写法
const addItemToCart = (cart, item) => {
return [...cart, { item, date: Date.now() }];
};
Не пишите глобальные функции
Загрязнение глобальных переменных — плохая практика в JS, так как может возникнуть конфликт с другой библиотекой, и пользователи API будут бесполезны, пока не столкнутся с исключением в продакшене. Рассмотрим пример: если вы хотите расширить роднойArray
метод, чтобы иметь функцию, которая может показать разницу между двумя массивамиdiff
Метод, что делать? Новые функции могут быть записаны вArray.prototype
, Но он может попытаться сделать то же самое с другим конфликтом библиотек. Если вы используете только другие библиотекиdiff
найти разницу между первым элементом и последним элементом массива? Вот почему просто используйте классы ES6 и просто расширяйтеArray
Причина глобальная будет лучше.
// 不好的写法
Array.prototype.diff = function diff(comparisonArray) {
const hash = new Set(comparisonArray);
return this.filter(elem => !hash.has(elem));
};
// 好的写法
class SuperArray extends Array {
diff(comparisonArray) {
const hash = new Set(comparisonArray);
return this.filter(elem => !hash.has(elem));
}
}
Попробуйте использовать функциональное программирование вместо императивного
JavaScript — это не функциональный язык, как Haskell, но он имеет функциональную подоплеку. Функциональные языки могут быть более лаконичными и их легче тестировать. Если можете, постарайтесь полюбить этот стиль программирования.
неправильное написание
const programmerOutput = [
{
name: "Uncle Bobby",
linesOfCode: 500
},
{
name: "Suzie Q",
linesOfCode: 1500
},
{
name: "Jimmy Gosling",
linesOfCode: 150
},
{
name: "Gracie Hopper",
linesOfCode: 1000
}
];
let totalOutput = 0;
for (let i = 0; i < programmerOutput.length; i++) {
totalOutput += programmerOutput[i].linesOfCode;
}
хорошее письмо
const programmerOutput = [
{
name: "Uncle Bobby",
linesOfCode: 500
},
{
name: "Suzie Q",
linesOfCode: 1500
},
{
name: "Jimmy Gosling",
linesOfCode: 150
},
{
name: "Gracie Hopper",
linesOfCode: 1000
}
];
const totalOutput = programmerOutput.reduce(
(totalLines, output) => totalLines + output.linesOfCode,
0
);
Состояние упаковки
// 不好的写法
if (fsm.state === "fetching" && isEmpty(listNode)) {
// ...
}
// 好的写法
function shouldShowSpinner(fsm, listNode) {
return fsm.state === "fetching" && isEmpty(listNode);
}
if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
// ...
}
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Избегайте использования безусловных
// 不好的写法
function isDOMNodeNotPresent(node) {
// ...
}
if (!isDOMNodeNotPresent(node)) {
// ...
}
// 好的写法
function isDOMNodePresent(node) {
// ...
}
if (isDOMNodePresent(node)) {
// ...
}
Не используйте слишком много условий
Это кажется невыполнимой задачей. Услышав это, большинство людей скажут: «Нет.if
заявление, как я могу что-нибудь сделать?» Ответ заключается в том, что вы можете использовать полиморфизм во многих ситуациях для достижения одной и той же задачи.
Второй вопрос обычно звучит так: «Это хорошо, но зачем мне это делать?» Ответом является концепция, упомянутая выше: функция должна делать только одну вещь. когда естьif
Когда вы объявляете классы и функции, вы сообщаете своим пользователям, что функция выполняет несколько функций.
неправильное написание
class Airplane {
// ...
getCruisingAltitude() {
switch (this.type) {
case "777":
return this.getMaxAltitude() - this.getPassengerCount();
case "Air Force One":
return this.getMaxAltitude();
case "Cessna":
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
}
хорошее письмо
class Airplane {
// ...
}
class Boeing777 extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getPassengerCount();
}
}
class AirForceOne extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude();
}
}
class Cessna extends Airplane {
// ...
getCruisingAltitude() {
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
избегать проверки типов
JavaScript нетипизирован, а это значит, что функции могут принимать аргументы любого типа. Иногда мы застреваем с этой свободой и хотели бы выполнять проверку типов в функциях. Есть много способов избежать этого. Первое, что нужно учитывать, — это согласованный API.
// 不好的写法
function travelToTexas(vehicle) {
if (vehicle instanceof Bicycle) {
vehicle.pedal(this.currentLocation, new Location("texas"));
} else if (vehicle instanceof Car) {
vehicle.drive(this.currentLocation, new Location("texas"));
}
}
// 好的写法
function travelToTexas(vehicle) {
vehicle.move(this.currentLocation, new Location("texas"));
}
Не переоптимизируйте
Современные браузеры выполняют большую работу по оптимизации во время выполнения. Во многих случаях, если вы оптимизируете, вы просто теряете время. Есть хорошие ресурсы, чтобы увидеть, где не хватает оптимизации, нам просто нужно нацелиться на то, где оптимизация необходима.
// 不好的写法
// 在旧的浏览器上,每一次使用无缓存“list.length”的迭代都是很昂贵的
// 会为“list.length”重新计算。在现代浏览器中,这是经过优化的
for (let i = 0, len = list.length; i < len; i++) {
// ...
}
// 好的写法
for (let i = 0; i < list.length; i++) {
// ...
}
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
оригинал:GitHub.com/Eardrum невооруженным глазом…
общаться с
Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.