变量
使用有意义和可理解的变量名
bad:
constyyyymmdstr = moment().format("YYYY/MM/DD");复制代码
good:
constcurrentDate = moment().format("YYYY/MM/DD");复制代码
使用具有解释性的变量
Bad:
constaddress ="One Infinite Loop, Cupertino 95014";constcityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;saveCityZipCode( address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);复制代码
Good:
constaddress ="One Infinite Loop, Cupertino 95014";constcityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;const[, city, zipCode] = address.match(cityZipCodeRegex) || [];saveCityZipCode(city, zipCode);复制代码
避免使用隐式映射
Bad:
constlocations = ["Austin","New York","San Francisco"];locations.forEach(l => { doStuff(); doSomeOtherStuff();// ...// ...// ...// Wait, what is `l` for again?dispatch(l);});复制代码
Good:
constlocations = ["Austin","New York","San Francisco"];locations.forEach(location => { doStuff(); doSomeOtherStuff();// ...// ...// ...dispatch(location);});复制代码
不要添加不必要的内容
Bad:
constCar = { carMake:"Honda", carModel:"Accord", carColor:"Blue"};functionpaintCar(car){ car.carColor ="Red";}复制代码
Good:
constCar = { make:"Honda", model:"Accord", color:"Blue"};functionpaintCar(car){ car.color ="Red";}复制代码
函数
函数参数因少于等于两个
限制你的函数参数数量是非常有必要的,这可以让你更容易测试你的函数。理想情况下函数参数等于小于两个,如果超过了两个,只能证明你的函数做的太多了,违背了单一功能的设计原则。
Bad:
functioncreateMenu(title, body, buttonText, cancellable){// ...}复制代码
Good:
functioncreateMenu({title,body,buttonText,cancellable}) {// ...}createMenu({title:"Foo",body:"Bar",buttonText:"Baz",cancellable: true});复制代码
不要使用标志作为函数的参数
函数功能应该保持单一功能。
bad
functioncreateFile(name, temp){if(temp) { fs.create(`./temp/${name}`); }else{ fs.create(name); }}复制代码
good
functioncreateFile(name){ fs.create(name);}functioncreateTempFile(name){ createFile(`./temp/${name}`);}复制代码
使用默认参数
Bad:
functioncreateMicrobrewery(name){constbreweryName = name ||"Hipster Brew Co.";// ...}复制代码
Good:
functioncreateMicrobrewery(name ="Hipster Brew Co."){// ...}复制代码
函数应该只处理同一抽象级别的功能
当你的函数要处理多个层级的功能,那你的函数就太复杂了。你应该把函数分割成各个层级以方便复用和测试。
Bad:
functionparseBetterJSAlternative(code){constREGEXES = [// ...];conststatements = code.split(" ");consttokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => {// ...}); });constast = []; tokens.forEach(token => {// lex...}); ast.forEach(node => {// parse...});}复制代码
Good:
functionparseBetterJSAlternative(code){consttokens = tokenize(code);constsyntaxTree = parse(tokens); syntaxTree.forEach(node => {// parse...});}functiontokenize(code){constREGEXES = [// ...];conststatements = code.split(" ");consttokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => { tokens.push(/* ... */); }); });returntokens;}functionparse(tokens){constsyntaxTree = []; tokens.forEach(token => { syntaxTree.push(/* ... */); });returnsyntaxTree;}复制代码
避免副作用
一个函数会产生副作用除非它只读取参数然后返回另外一个参数
Bad:
// Global variable referenced by following function.// If we had another function that used this name, now it'd be an array and it could break it.letname ="Ryan McDermott";functionsplitIntoFirstAndLastName(){ name = name.split(" ");}splitIntoFirstAndLastName();console.log(name);// ['Ryan', 'McDermott'];复制代码
Good:
functionsplitIntoFirstAndLastName(name){returnname.split(" ");}constname ="Ryan McDermott";constnewName = splitIntoFirstAndLastName(name);console.log(name);// 'Ryan McDermott';console.log(newName);// ['Ryan', 'McDermott'];复制代码
Bad:
constaddItemToCart = (cart, item) => { cart.push({ item,date:Date.now() });};复制代码
Good:
constaddItemToCart =(cart, item) =>{return[...cart, { item,date:Date.now() }];};复制代码
封装条件语句
Bad:
if(fsm.state ==="fetching"&& isEmpty(listNode)) {// ...}复制代码
Good:
functionshouldShowSpinner(fsm, listNode){returnfsm.state ==="fetching"&& isEmpty(listNode);}if(shouldShowSpinner(fsmInstance, listNodeInstance)) {// ...}复制代码
避免使用否定语句
Bad:
functionisDOMNodeNotPresent(node){// ...}if(!isDOMNodeNotPresent(node)) {// ...}复制代码
Good:
functionisDOMNodePresent(node){// ...}if(isDOMNodePresent(node)) {// ...}复制代码
对象和数据结构
使用setters跟getters
当你想做的不仅仅是获取一个对象属性,你不需要查找和更改代码库中的每个访问器。
使在执行集合时添加验证变得简单。
封装内部表示。
在获取和设置时易于添加日志记录和错误处理。
可以延迟加载对象的属性,例如从服务器获取。
Bad:
functionmakeBankAccount(){// ...return{ balance:0// ...};}constaccount = makeBankAccount();account.balance =100;复制代码
Good:
functionmakeBankAccount(){// this one is privateletbalance =0;// a "getter", made public via the returned object belowfunctiongetBalance(){returnbalance; }// a "setter", made public via the returned object belowfunctionsetBalance(amount){// ... validate before updating the balancebalance = amount; }return{// ...getBalance, setBalance };}constaccount = makeBankAccount();account.setBalance(100);复制代码
类
使用链式调用
Bad:
classCar{constructor(make, model, color) {this.make = make;this.model = model;this.color = color; } setMake(make) {this.make = make; } setModel(model) {this.model = model; } setColor(color) {this.color = color; } save() { console.log(this.make,this.model,this.color); }}const car = new Car("Ford","F-150","red");car.setColor("pink");car.save();复制代码
Good:
classCar{constructor(make, model, color) {this.make = make;this.model = model;this.color = color; } setMake(make) {this.make = make;//NOTE:Returning this for chainingreturnthis; } setModel(model) {this.model = model;//NOTE:Returning this for chainingreturnthis; } setColor(color) {this.color = color;//NOTE:Returning this for chainingreturnthis; } save() { console.log(this.make,this.model,this.color);//NOTE:Returning this for chainingreturnthis; }}const car = new Car("Ford","F-150","red").setColor("pink").save();复制代码
如果对于学习编程有很多疑惑,没有思路,不知道如何有效率的学习,可以添加我的前端交流学习群 895757445,需要最新系统的学习教程也可以管我要。做了很多年开发,对于学习方式,如何提高自己的技术有一定的经验,术业有专攻,多跟有经验的人交流学习,对这个行业信息了解的多,职业发展的空间就越大
网友评论