常量赋值
引用数据类型
包括接口中返回的数据,要做好兜底
let lastName = fullName[1] || ''
let propertyValue=Object.attr || 0
指明类型
要按强类型风格写代码定义变量的时候要指明类型,并且在变量声明之后,不要随意的去更改变量的数据类型
// 假设声明三个变量a,b,c
let a,b,c; // difference,定义变量时没有指明类型
let a = "", b = [], c = {}; // good
逻辑判断
==
逻辑判断注意
==
表示只要值相等即为真,===
要求不仅值相等,而且也要求类型相同
使用== 有时候会达不到预期的结果,埋下隐患
0 == '' // true
0 == '0' // true
'' == 0 // true
'' == '0' // false
false == '0' // true
false == 'false' // false
false == undefined // false
false == null // false
null == undefined // true
true == 1 // true
数据类型不确定
如果变量的数据类型不确定,那咱就手动的转换一下,让它确定
let total = "6";
if(parseInt(total) === 6){} // grace 手动转换一下数据类型
数组
数组拷贝
let items=['1','2','3'];
const itemCopy = [...items]
// joining arrays
const odd = [1, 3, 5 ];
const nums = [2 ,4 , 6, ...odd];
变量赋值
const Arr = [1, 2, 3, 4];
const [first, second] = Arr;
函数的命名
返回布尔值函数应以is/can/has等单词开头,能够让人更直观的了解到这个函数的功能;获取接口中的数据使用get开头进行命名,动作函数要以动词开头。
// grace
let isSupport = () => {};
let canUpdate = () => {};
let geUserInfo = (user) => {}
let setUserInfo = (user) => {}
优先使用箭头函数
// grace 是不是看着更简介优雅了
let findAge = (arr, age)=> arr.filter(num => num === age)
函数的入参
函数的入参,是能够让使用者,在调用这个函数的时候,能够更加的清晰明了的把这个函数所需要的参数传递给函数,不容易出现,参数传递错误(参数的顺序颠倒等)一些低级,而又不好查找的问题
// difference
// true和false啥意思,没有个注释的话,看上去就是一脸懵逼
function getImages(api, true, false);
// grace
// 一目了然,知道这些true和false是啥意思
function getImages({
imageApi: api,
includePageBackground: true,
compress: false,
})
接收参数
如果函数的的参数是对象,也要优先使用解构赋值,上代码
// 假设现在的场景是获取用户的信息上的现用名,和曾用名
// difference
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
}
// commonly
function getFullName(obj) {
const { firstName, lastName } = obj;
}
// grace
function getFullName({ firstName, lastName }) {
}
// grace 给它个默认值
function getFullName({firstName, lastName = '无'}) {
}
// 觉得参数的名称太长,咱再来个重命名 解构时重命名简化命名
// grace
function getFullName ({firstName: first, lastName: last}) {
}
参数效验
更少的嵌套,不满足条件尽早 return,尽可能的减少嵌套,嵌套的层级越少,函数看着越简洁优雅
function test(name, sex = 1) {
// 不满足条件尽早抛出错误
if (!name){
throw new Error('没有传递name参数');
}
}
函数的出参
对象作为返回值,更便于以后添加返回值,以及更改返回值的顺序,相对于数组更加的灵活,更便于扩展
// 函数返回多个值,推荐使用对象作为函数的返回值
// commonly
function processInput(input) {
return [left, right, top, bottom];
}
// grace
function processInput(input) {
return { left, right, top, bottom };
}
const { left, right } = processInput(input);
立即执行函数
立即执行函数也推荐写成箭头函数的形式。首先是因为更简洁,并且也绑定好 this(箭头函数不会去改变this的指向)。
(() => {
console.log('立即执行函数');
})();
优先使用函数式编程
// difference
for(i = 1; i <= 10; i++) {
a[i] = a[i] +1;
}
// grace
let b = a.map(item => ++item) //是不是更简洁了
函数中过多的采用if else
// commonly
if (a === 1) {
//...
} else if (a ===2) {
// ...
} else if (a === 3) {
//...
} else {
//...
}
// 一般
switch(a) {
case 1:
//....
case 2:
//....
case 3:
//....
default:
//....
}
// grace ===》》》 Object
const fruit = {
1: ['1', '11'],
2: ['2', '22'],
3: ['3', '33']
};
let test = (a) => {
return fruit[a] || [];
}
// grace ===》》》 Map
const fruit = newMap()
.set('张三', ['张三丰', '张三力'])
.set('李四', ['李思维', '李素丽'])
let test = (a) => {
return fruit.get(a) || [];
}
// grace ===》》》filter
const fruits = [
{ name: '张三', work: 'js' },
{ name: '李四', work: 'php' },
{ name: '王五', work: 'java' },
];
let test = (a) => {
return fruits.filter(item => item.name === a);
}
// grace===》》》策略模式
let handler = {
1: () => {
//....
},
2: () => {
//....
},
3: () => {
//....
},
default: () => {
//....
}
}
handler[a]() || handler['default']()
温馨小提示
一个函数完成一个独立的功能,不要一个函数混杂多个功能,在项目开发中有一条非常重要的原则【单一原则】所谓的单一原则就是,一个函数(文件),只做一件事情,在开发当中,没有那个项目是开发完成之后,就结束了。需要不断的更新,维护,那么单一原则,就是为了方便开发,和维护的,不要让一个函数“又当爹,又当妈”,这样代码的耦合性太高了,不好维护
其他
判断数组长度
// difference
if (arr.length !== 0) {
//...
}
// grace
if (arr.length) {
//...
}
// difference
if (arr.length === 0) {
//...
}
// grace
if (!arr.length) {
//...
}
逻辑运算符
if (a === 1) {
b()
}
//可以写成
a === 1 && b()
const arr = [1,2,3];
if(!arr.length){
b()
}
//可以写出
arr.length || b()
// &&判断依赖的键是否存在,防止报错'xxx of undfined'
let user = {
name: 'Symbol卢',
age: 18,
children: {
name: '小Symbol卢'
}
}
let childrenName = user.children && user.childre.name
三目运算符
// difference
const a = '';
let b;
if( a === '' ){
b = 'no'
} else {
b = 'ok'
}
const a = ''
let b = a ? 'no' : 'ok'; // 'ok'
函数定义
/**
* @description: 数据类型的检测的第二种方式
* @param {any} data 要检测数据类型的变量
* @return {string} type 返回具体的类型名称【小写】
*/
export const isTypeOf = (data) => {
return Object.prototype.toString.call(data).replace(/[object (\w+)]/, '$1').toLowerCase()
}
使用 Array.includes 来处理多重 || 条件
// difference
if (a === 1 || a === 2 || a === 3 || a === 4) {
//...
}
// grace
let arr = [1, 2, 3, 4]
if (arr.includes(a)) {
//...
}
使用 Array.every 和 Array.some 来处理全部/部分满足条件
// grace
const users = [
{ name: '张三', sex:1 },
{ name: '李四', sex:2 },
{ name: '王五', sex:1 }
];
function test() {
// 条件:(简短形式)所有的用户都必须是女
const isAllGirl = users.every(item => item.sex === 1);
// 条件:至少一个用户是男的
const isAnyMan = users.some(item => item.sex === 2);
}
使用正则表达式
const imgType ='jpg'
if(imgType === 'jpg' || imgType === 'png' || imgType === 'gif'){
console.log('is image')
}
// 使用match匹配正则表达式
if(imgType.match(/.*?(gif|png|jpg)/gi)){
console.log('is image')
}
连接字符串
let name = 'Symbol'
let message = 'Hello,I'm' + name + 'take care '// 采用传统加号,看着很冗余,且容易出错
// 艾玛,模板字符香,真想
let message = `Hello,I'm ${name} take care `