JavaScripter 每日指南
JavaScripter 每日指南
JavaScripter 每日指南
本文档是对 js 中良好编程实践的总体总结。
该文件的一部分基于 Airbnb 指南,另一部分基于专业经验。
https://github.com/airbnb/javascript
NODE.JS部分是对不同阅读材料和我自己对该技术的经验的总结。
内容列表
节点.JS
范式-FP
JavaScript 是一种多范式编程语言。虽然在代码中混合使用多种范式更好,但最好只专注于一种。如今的趋势是专注于函数式编程,无论是开发前端还是后端。
这些是一些有用的函数式编程原则。
- 功能思考
- Lambda
- 咖喱
- 无国籍
- 组合函数
- 纯函数:
- 副作用
- 函子
- 高阶函数
- 头等舱
- 突变
👉 要继续阅读有关 FP 的信息,请访问此链接:
https://github.com/damiancipolat/Functional_programming_in_JS
命名约定
js中如何命名对象。
根据Airbnb指南点:
23.1
,,,23.2
23.3
23.6
-
避免使用单字母名称。命名时应尽量描述清楚。
// bad function q() { } // good function query() { }
-
命名对象、函数和实例时使用驼峰式命名法。
// bad const OBJEcttsssss = {}; const this_is_my_object = {}; function c() {} // good const thisIsMyObject = {}; function thisIsMyFunction() {}
-
仅在命名构造函数或类时使用PascalCase 。
// bad function user(options) { this.name = options.name; } const bad = new user({ name: 'nope', }); // good class User { constructor(options) { this.name = options.name; } } const good = new User({ name: 'yup', });
-
常量中仅使用大写字母。
// allowed but does not supply semantic value export const apiKey = 'SOMEKEY'; // better in most cases export const API_KEY = 'SOMEKEY';
分号
根据Airbnb的指南要点:
21.1
。
为什么?当 JavaScript 遇到没有分号的换行符时,它会使用一组称为“自动分号插入”的规则来确定是否应将该换行符视为语句的结尾,并且(顾名思义)如果它认为是,则会在代码的换行符前添加一个分号。然而,ASI 包含一些特殊的行为,如果 JavaScript 误解了你的换行符,你的代码就会崩溃。随着 JavaScript 新功能的加入,这些规则将变得更加复杂。明确终止语句并配置 linter 以捕获缺失的分号将有助于避免出现问题。
```javascript
// bad
function foo() {
return
'search your feelings, you know it to be foo'
}
// good
const luke = {};
const leia = {};
[luke, leia].forEach((jedi) => {
jedi.father = 'vader';
});
```
评论
在您的项目中标准化 js 注释。VisualStudio 代码可以识别此格式。
使用 JSDOC https://jsdoc.app/about-getting-started.html格式。
-
使用块注释。
/** This is a description of the foo function. */ function foo() { }
-
使用 JSDOC 标签来描述一个函数。
/** * Represents a book. * @constructor * @param {string} title - The title of the book. * @param {string} author - The author of the book. */ function Book(title, author) { }
承諾。
改变处理回调的方式。
- 如果您使用回调样式函数,请将其包装在承诺中:
function doAsync(function(err, data) {
if (err) {
// error
} else {
// success
}
});
- 承诺:
const doAsyncPomise= () =>{
return new Promise((resolve,reject)=>{
if (err)
reject(err);
else
resolve(..);
});
}
错误处理
处理错误的不同方式。
- 使用同步功能:
try{
makeSomething();
} catch(err){
rollBack();
}
- 使用返回承诺的函数:
makeSomething()
.then(data=>{
//....
})
.catch(err=>{
rollback(...)
});
- 使用 async/await 函数:
const run = async ()=>{
try{
const result = await makeSomething();
} catch(err){
rollBack(..)
}
};
- 避免返回“错误结构”来传达错误,最好引发异常。
//bad
const run = (param)=>{
const result = makeSomething(param);
if (result){
return result;
} else {
return {
error:'processing error'
};
}
}
//good
const run = (param)=>{
if (!param)
throw new Error('Bad parameters');
const result = makeSomething(param);
if (!result)
throw new Error('Processing error');
return result;
}
比较
改进你的比较方法。
根据Airbnb指南点:
15.1
,,,,,,15.2
15.3
15.5
15.6
15.7
- 使用 === 和 !== 而不是 == 和 !=。
-
条件语句(例如 if 语句)使用 ToBoolean 强制转换来评估其表达式。https
://github.com/airbnb/javascript/blob/master/README.md#comparison--ifif ([0] && []) { // true // an array (even an empty one) is an object, objects will evaluate to true }
-
布尔值的用户快捷方式。
// bad if (isValid === true) { // ... } // good if (isValid) { // ... }
-
三元表达式不应嵌套,通常是单行表达式。
// bad const foo = maybe1 > maybe2 ? "bar" : value1 > value2 ? "baz" : null; // split into 2 separated ternary expressions const maybeNull = value1 > value2 ? 'baz' : null; // better const foo = maybe1 > maybe2 ? 'bar' : maybeNull; // best const foo = maybe1 > maybe2 ? 'bar' : maybeNull;
-
三元表达式不应嵌套,通常是单行表达式。
// bad const foo = a ? a : b; const bar = c ? true : false; const baz = c ? false : true; // good const foo = a || b; const bar = !!c; const baz = !c;
迭代次数
以实用的方式处理 lopps。
根据Airbnb的指南要点:
11.1
-
不要使用迭代器,更喜欢使用 js 高阶函数而不是 for / for..in
// bad const increasedByOne = []; for (let i = 0; i < numbers.length; i++) { increasedByOne.push(numbers[i] + 1); } // good const increasedByOne = []; numbers.forEach((num) => { increasedByOne.push(num + 1); });
功能
如何以现代方式处理功能。
根据Airbnb指南点:
7.1
,,,,,,,7.5
7.6
7.7
7.10
7.12
7.13
-
使用命名箭头函数表达式代替函数声明。
// bad function foo() { // ... } // bad const foo = () => { // ... };
-
永远不要将参数命名为arguments..
// bad function foo(name, options, arguments) { // ... } // good function foo(name, options, args) { // ... } `` - Never use arguments, opt to use rest syntax ... instead.
javascript
// 错误
函数 concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}// 好的
函数 concatenateAll(...args) {
return args.join('');
}
`` -
避免使用默认参数的副作用。`
javascript const b = 1; // bad function count(a = b++) {console.log (a); } count(); // 1 count(); // 2 count(3); // 3 count(); // 3
- 永远不要改变参数。`javascript
// bad function f1(obj) { obj.key = 1; }
// 好的
函数 f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
`` - 永远不要改变参数。`javascript
细绳
处理字符串的最佳方法。
根据Airbnb指南点:
6.1
,,,6.2
6.3
6.4
-
对字符串使用单引号 '',不要与 "" 混合使用。
// bad const name = "Bart"; // bad - template literals should contain interpolation or newlines const name = `Marge`; // good const name = 'Homer';
-
使用模板字符串而不是将字符串与值连接起来。
const name = 'Bart'; const surname = 'Simpson'; // bad const txt = 'hello mr. '+name+', '+surname'; // good const txt = `hello mr. ${name}, ${surname}`; `` **[⮬ back to top](#table-of-contents)**
解构
解构只是意味着将复杂的结构分解成更简单的部分。
根据Airbnb指南点:
5.1
,,5.2
5.3
-
访问和使用对象的多个属性时使用解构。
javascript // bad function getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; return `${firstName} ${lastName}`; } // good function getFullName(user) { const { firstName, lastName } = user; return `${firstName} ${lastName}`; }
-
使用数组解构。
javascript // bad const first = arr[0]; const second = arr[1]; // good const [first, second] = arr; `` **[⮬ back to top](#table-of-contents)**
数组
数组操作实践。
根据Airbnb指南点:
4.1
,,,4.3
4.4
4.7
- 了解这个数组原型很重要:
map
,,,,,,,,。httpsreduce
: //developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/prototypeforEach
filter
find
push
pop
slice
-
使用文字语法来创建数组。
`
javascript
// 不好
const items = new Array();// 好
const items = [];`
- 使用数组扩展
...
来复制数组:`javascript // bad const len = items.length; const itemsCopy = []; let i;
对于(i = 0; i < len; i += 1){
itemsCopy[i] = items[i];
}// 好
const itemsCopy = [...items];`
- 要将可迭代对象转换为数组,请使用扩展
...
而不是Array.from
。`javascript // bad const items = new Array();
// 好
const items = [];`
- 使用数组扩展
...
来复制数组:`javascript // bad const len = items.length; const itemsCopy = []; let i;
对于(i = 0; i < len; i += 1){
itemsCopy[i] = items[i];
}// 好
const itemsCopy = [...items];`
- 在数组方法回调中使用返回语句:`
javascript // bad inbox.filter((msg) => { const { subject, author } = msg; if (subject === 'Mockingbird') { return author === 'Harper Lee'; } else { return false; } });
// 好
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird') {
return author === 'Harper Lee';
}返回 false;
});`
- 使用数组扩展
对象
关于如何改进对象操作的一些技巧。
根据Airbnb指南点:
3.1
,,,,,3.3
3.4
3.6
3.8
-
使用文字语法来创建对象。` javascript
// bad const item = new Object();// 好
const item = {};`
-
使用对象方法简写。`
javascript // badconst atom = { value: 1,
addValue:函数(值){
返回原子.value + value;
},
};// 好的
const atom = {
值: 1,添加值(值){
返回原子.值+值;
},
};`
-
使用属性值简写。`
javascript const bart = 'BartSimpson
';// 不好
const obj = {
bart: bart,
};// 好的
const obj = {
bart,
};`
-
仅引用示例中无效标识符的属性'bla- bla'。` javascript
// bad const bad = { 'foo': 3, 'bar': 4, 'data-blah': 5, };// 好
const good = {
foo: 3,
bar: 4,
'bla-bla': 5,
};`
-
如果您需要访问一个对象属性的动态:
`javascript
const person = {
name:'Damian',
age:32
};const key = 'age';
console.log(person[key]);`
-
与 Object.assign 相比,优先使用对象展开运算符来进行浅拷贝对象:
`javascript
// bad
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }// 好的
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }`
特性
根据Airbnb指南要点:
12.1
,12.2
-
访问属性时使用点符号。
`
javascript
const luke = {
jedi: true,
age: 28,
};// 不好
const isJedi = luke['jedi'];// 好
const isJedi = luke.jedi;`
- 使用变量访问属性时使用括号表示法 []:`
javascript const person = { name:'Damian', age:32 };
const key = 'age';
console.log(person[key]);`
- 使用变量访问属性时使用括号表示法 []:`
原语
js中提供的基本类型数据。
根据Airbnb的指南要点:
1.1
当您访问原始类型时,您可以直接对其值进行操作。
- 细绳
- 数字
- 布尔值
- 无效的
- 不明确的
- 象征
变量
关于如何在 javascript 中处理和声明变量的一些要点。
根据Airbnb指南点:
2.1
,,,,,,,,2.2
13.1
13.2
13.3
13.4
13.5
13.8
- 避免在项目中使用全局变量。
- 避免
var
在变量声明中使用,请使用const
。 - 如果必须重新分配引用,请使用
let
而不是const
。 - 将您的全部分组
const
,然后将您的全部分组let
。 -
删除未使用的变量。
`
javascript
// 错误
var a = 1;
var b = 2;// 好
const a = 1;
const b = 2;// 不好
var count = 1;
if (true) {
count += 1;
}// 好,使用 let。let
count = 1;
if (true) {
count += 1;
}// 不好
superPower = new SuperPower();// 好
const superPower = new SuperPower();`
TL;DR;
不要使用:
- 没有全局变量。
- 使用“var”声明变量。
- 使用“function”关键字声明函数。
- 避免在循环中使用“for”。
- 数组推送,不变性。
- 班级。
- 使用 delete 删除对象属性。
- 避免嵌套 if。
- 否则,如果。
- 重度嵌套https://www.w3.org/wiki/JavaScript_best_practices#Avoid_heavy_nesting。
- 避免向可以在模块中使用的函数添加原型。
使用:
- 函数中通用的代码,遵循DRY原则。
- 快捷符号。
- 在 Object.assign 上展开运算符(airbnb 3.8)。
- 帕斯卡大小写命名。
- 将你的代码模块化。
- const 和 let!。
- 用于创建对象的文字语法(airbnb 3.1)。
- 创建对象时计算属性名称(airbnb 3.2)。
- 属性值简写(airbnb 3.4)。
- 将你的速记属性分组到你的对象的开头(airbnb 3.5)。
- 使用文字语法创建数组(airnbnb 4.1)。
- 使用数组扩展...复制数组。(airbnb 4.3)。
- 使用 spreads ... 代替 Array.from。(airbnb 4.4)。
- 在数组方法回调中使用返回语句(airbnb 4.7)。
新公共管理(NPM):
一些在 npm 中使用的有趣技巧和命令。
####npm init
每当你从头开始一个项目时执行此命令
####npm install {dependency} --save
使用 save 参数执行此命令,当需要安装新模块时,save 参数会将依赖关系记录在 package.json 中
####npm install {dependency} --save--dev
安装新的依赖项,但仅用于开发目的,例如单元测试。
####npm install
将从 package.json 安装“dependencies”和“devDependencies”。
####npm install --dev
当你只需要将 dev 依赖项示例安装到 ci/cd 步骤中以运行测试时,请运行此命令。此命令将仅从 package.json 安装“devDependencies”
####npm install --production
将仅从 package.json 安装“依赖项”。
####npm audit
此命令列出 package.json 中安装的依赖项的所有安全漏洞
####npm audit --fix
子命令自动安装易受攻击的依赖项的兼容更新。
包.json:
- 版本:
使用version
属性保存当前项目版本遵循 SEMVER 规则,http://semver.org
`json
{
"name": "api",
"version": "1.0.0",
"description": "orders api",
"main": ""
}
`
SEMVER 规则:
MAJOR:进行不兼容 API 更改时的版本。MINOR :以向后兼容的方式添加功能时的版本。PATCH :进行向后兼容的错误修复时的版本
。
- 依赖项:
确保您将依赖模块保存在“devDependencies”部分。
- 脚本:
完成 package.json 的脚本部分很重要,基本脚本应该是:
`sh
npm start
npm test
npm deploy
`
建议:
- 使用 npm mayor / npm minor 更改版本。
- 在生产中设置 NODENV。
- 将公共代码拆分到模块中。
- 不要使用同步功能进行 i/o;
- 使用流。
- 使用异常传达错误。
- 尝试/捕获是否可以解决异常。
- 善用承诺。
- Promise.all 始终并行化
- 包装 promise.all 以避免部分执行。
- 使用 Async / await 替代 promise.then
- 不要使用回调函数,而要用 Promise 代替它们。
- 避免过多嵌套。
- 避免使用 else if。
- 避免嵌套 if。
- 避免使用全局变量。
- 不要滥用安装模块
- 首先考虑使用节点核心模块而不是搜索 npm 模块。
- 创建一个记录器包装器,而不是使用 console.log,(winston)
- 为不同项目中使用的通用代码创建私有 npm 模块。重复利用。
- 避免“核心”模式,其想法是避免将应用程序的整个业务代码放在一组 npm 模块中
- 不要使用类,最好将重点放在导出函数的模块上。
- 外部化您的配置,使以后的测试变得简单。
堆栈:
一些模块的推荐。
- 用于测试:Jest 或 Mocha / Chai / Proxyquire。
- 伐木者:温斯顿。
- 对于 Api:Expressjs、Hapijs、Restify。
- 对于 SQL:Sequlize。
- 对于 Mongodb:Mongoose。
- 对于无服务器:无服务器框架或 AWS-CDK https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html
- 对于请求:node-fetch 或 axios。
- 对于时间:moment/moment-timezone。
- 对于 lint:es-lint。
- 对于模式验证:Joi
玩得开心!🛸🐧🐲👽👆👻👺
文章来源:https://dev.to/damxipo/guide-for-the-daily-javascripter-87o