javascript代码重构之:写好函数

news/2024/7/19 13:07:12 标签: javascript, js, 函数

1、函数要短小,一个函数只做一件事

如果函数做了较多的事情,它就难以组合、测试和推测。同时让函数只做一件事情的时候,它们就很容易重构。

javascript">// Bad
function
 showStudent(ssn){
const
 student = db.
get
(ssn);
if
(student !== 
null
){
        document.querySelector(
`#${elementId}`
).innerHTML =
`${student.ssn},
            ${student.firstName},
            ${student.lastName}`
} 
else
{
thrownew
Error
(
'student not found'
)
}
}
showStudent(
'444-44-4444'
)
// Good
function
 findStudent(db,id){
const
 student = db.
get
(id);
if
(student === 
null
){
thrownew
Error
(
'student not found'
);
}
};
function
 getStudentInfo(student){
return
`${student.ssn},${student.firstName},${student.lastName}`
};
function
 showStudentInfo(elementId,info){
    document.querySelector(elementId).innerHTML = info;
}
function
 showStudent(ssn){
const
 student = findStudent(ssn);
let
 studentInfo = getStudentInfo(student);
    showStudentInfo(elementId,studentInfo);
}

只是做了些许的改进,但已开始展现出很多的优势:undefined

2、每个函数一个抽象层级

函数中混杂不同的抽象层级,往往让人迷惑。读者可能无法判断某个表达式是基础概念还是细节。更恶劣的是,就像破损的窗户,一旦细节和基础概念混杂,更多的细节就会在函数中纠结起来。理解抽象层次请参考:抽象层次

javascript">// Bad
function
 parseBetterJSAlternative(code) {
let
 REGEXES = [
// ...
];
let
 statements = code.split(
' '
);
let
 tokens;
  REGEXES.forEach((REGEX) => {
    statements.forEach((statement) => {
// ...
})
});
let
 ast;
  tokens.forEach((token) => {
// lex...
});
  ast.forEach((node) => {
// parse...
})
}
// Good
function
 tokenize(code) {
let
 REGEXES = [
// ...
];
let
 statements = code.split(
' '
);
let
 tokens;
  REGEXES.forEach((REGEX) => {
    statements.forEach((statement) => {
// ...
})
});
return
 tokens;
}
function
 lexer(tokens) {
let
 ast;
  tokens.forEach((token) => {
// lex...
});
return
 ast;
}
function
 parseBetterJSAlternative(code) {
let
 tokens = tokenize(code);
let
 ast = lexer(tokens);
  ast.forEach((node) => {
// parse...
})
}

3、使用描述性的名称

函数越短小,功能越集中,就越便于取个好名字。长而具有描述性的名称,要比短而令人费解的名称好。长而具有描述性的名称,要比描述性的长注释好。使用某种命名约定,让函数名称中的多个单词容易阅读,然后使用这些单词给函数取个能说明其功能的名称。

javascript">// Bad
function
 dateAdd(date, month) {
// ...
}
let
 date = 
new
Date
();
// 很难从函数名了解到加了什么
dateAdd(date, 
1
);
function
 write(name){
// ...
}
function
 assertEqual(a,b){
// ...
}
// Good
function
 dateAddMonth(date, month) {
// ...
}
let
 date = 
new
Date
();
dateAddMonth(date, 
1
);
// 告诉我们 name 是一个 field
function
 writeField(name){
// ...
}
// 能更好的解释参数的顺序和意图
function
 assertExpectedEqualActual(expected,actual){
// ...
}

4、函数参数

最理想的参数数量是零,其次是一(单参数函数),再次是二(双参数函数),应尽量避免三(三参数函数)。有足够的理由才能使用三个以上参数。如果函数需要三个以上参数,就说明其中一些参数应该放在一个对象中了。参数越多,函数越不容易理解,同时编写能确保参数的各种组合运行正常的测试用例越困难。

5、避免副作用

如果一个函数不是获取一个输入的值并返回其它值,它就有可能产生副作用。这些副作用可能是写入文件、修改一些全局变量、屏幕打印或者日志记录、查询HTML文档、浏览器的cookie或访问数据库。无论哪种情况,都具有破坏性,会导致古怪的时序性耦合及顺序依赖。现在你确实需要在程序中有副作用。像前面提到的那样,你可能需要写入文件。现在你需要做的事情是搞清楚在哪里集中完成这件事情。不要使用几个函数或类来完成写入某个特定文件的工作。采用一个,就一个服务来完成。

javascript">// Bad
// 下面的函数使用了全局变量。
// 如果有另一个函数在使用 name,现在可能会因为 name 变成了数组而不能正常运行。
var
 name = 
'Ryan McDermott'
;
function
 splitIntoFirstAndLastName() {
  name = name.split(
' '
);
}
splitIntoFirstAndLastName();
console.log(name); 
// ['Ryan', 'McDermott'];
// Good
function
 splitIntoFirstAndLastName(name) {
return
 name.split(
' '
);
}
var
 name = 
'Ryan McDermott'
var
 newName = splitIntoFirstAndLastName(name);
console.log(name); 
// 'Ryan McDermott';
console.log(newName); 
// ['Ryan', 'McDermott'];

6、删除重复代码

重复代码意味着你要修改某些逻辑的时候要修改不止一个地方的代码。

javascript">// Bad
function
 showDeveloperList(developers) {
  developers.forEach(developers => {
var
 expectedSalary = developer.calculateExpectedSalary();
var
 experience = developer.getExperience();
var
 githubLink = developer.getGithubLink();
var
 data = {
      expectedSalary: expectedSalary,
      experience: experience,
      githubLink: githubLink
};
    render(data);
});
}
function
 showManagerList(managers) {
  managers.forEach(manager => {
var
 expectedSalary = manager.calculateExpectedSalary();
var
 experience = manager.getExperience();
var
 portfolio = manager.getMBAProjects();
var
 data = {
      expectedSalary: expectedSalary,
      experience: experience,
      portfolio: portfolio
};
    render(data);
});
}
// Good
function
 showList(employees) {
  employees.forEach(employee => {
var
 expectedSalary = employee.calculateExpectedSalary();
var
 experience = employee.getExperience();
var
 portfolio;
if
(employee.type === 
'manager'
) {
      portfolio = employee.getMBAProjects();
} 
else
{
      portfolio = employee.getGithubLink();
}
var
 data = {
      expectedSalary: expectedSalary,
      experience: experience,
      portfolio: portfolio
};
    render(data);
});
}

7、使用更优雅写法

1、使用默认参数代替短路表达式

javascript">// Bad
function
 writeForumComment(subject, body) {
  subject = subject || 
'No Subject'
;
  body = body || 
'No text'
;
}
// Good
function
 writeForumComment(subject = 
'No subject'
, body = 
'No text'
) {
...
}

2、用 Object.assign 设置默认对象

javascript">// Bad
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);
// Good
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 等于: {title: "Foo", body: "Bar", buttonText: "Baz", cancellable: true}
// ...
}
createMenu(menuConfig);

3、喜欢上命令式编程之上的函数式编程

javascript">// Bad
const
 programmerOutput = [
{
    name: 
'Uncle Bobby'
,
    linesOfCode: 
500
}, {
    name: 
'Suzie Q'
,
    linesOfCode: 
1500
}, {
    name: 
'Jimmy Gosling'
,
    linesOfCode: 
150
}, {
    name: 
'Gracie Hopper'
,
    linesOfCode: 
1000
}
];
var
 totalOutput = 
0
;
for
(
var
 i = 
0
; i < programmerOutput.length; i++) {
  totalOutput += programmerOutput[i].linesOfCode;
}
// Good
const
 programmerOutput = [
{
    name: 
'Uncle Bobby'
,
    linesOfCode: 
500
}, {
    name: 
'Suzie Q'
,
    linesOfCode: 
1500
}, {
    name: 
'Jimmy Gosling'
,
    linesOfCode: 
150
}, {
    name: 
'Gracie Hopper'
,
    linesOfCode: 
1000
}
];
var
 totalOutput = programmerOutput
.map((programmer) => programmer.linesOfCode)
.reduce((acc, linesOfCode) => acc + linesOfCode, 
0
);

8、不要把标记用作函数参数

标记告诉你的用户这个函数做的事情不止一件。但是函数应该只做一件事。如果你的函数中会根据某个布尔参数产生不同的分支,那就拆分这个函数

javascript">// Bad
function
 createFile(name, temp) {
if
(temp) {
    fs.create(
'./temp/'
+ name);
} 
else
{
    fs.create(name);
}
}
// Good
function
 createTempFile(name) {
  fs.create(
'./temp/'
+ name);
}
function
 createFile(name) {
  fs.create(name);
}

http://www.niftyadmin.cn/n/658222.html

相关文章

ORACLE UPDATE 语句语法与性能分析看法 [转]

update 作者:未知   ORACLE UPDATE 语句语法与性能分析的一点看法 为了方便起见,建立了以下简单模型,和构造了部分测试数据: 在某个业务受理子系统BSS中&#xff0c; --客户资料表 create table customers ( customer_id number(8) not null, -- 客户标示 cit…

推荐几个大厂的前端代码规范,你也能写出诗一样的代码!

前端代码规范 代码千万行&#xff0c;安全第一行&#xff1b;前端不规范&#xff0c;同事两行泪。 腾讯 腾讯 包含内容也挺多的&#xff1a; PC端专题&#xff1a;快速上手、文件目录、页面头部、通用title、通用foot、统计代码、兼容测试 移动端专题&#xff1a;快速上手…

又到了票贩子发一回的机会了

每到春节前后&#xff0c;凡是要出门的都会有同样的感受&#xff0c;那就是 火车票可真难买呀。我也是有亲身经历的。好像是&#xff10;&#xff14;年春节&#xff0c;我的两个亲戚要做初六的火车去上海&#xff0c;我去排队买票&#xff0c;售票员亲口告诉我&#xff0c;明…

推荐 7 个 Github 上近 200k Star 的计算机学习资源,练好前端内功的秘籍!

computer-science Star :58k Github 地址&#xff1a;https://github.com/ossu/computer-science 介绍&#xff1a;通往计算机科学免费自学教育之路&#xff01; OSSU课程是使用在线材料进行的完整的计算机科学教育。它不仅用于职业培训或专业发展。 它适用于那些希望对所…

vbscript下格式化时间和日期的函数

我们有时候遇到的日期格式可能是2004-1-12 ,系统自动将月份中的0去掉了&#xff0c;但是有时候我们需要完整的日期格式 &#xff0c;如&#xff1a;2004-01-12 那么怎么办呢&#xff1f;下面的几个函数可以轻松搞定。。。。。。 将一个一位的数字前面加零function FillZero…

JavaScript 中哪一种循环最快呢?

究竟哪一种循环更快&#xff1f; 答案其实是&#xff1a; for&#xff08;倒序&#xff09; 最让我感到惊讶的事情是&#xff0c;当我在本地计算机上进行测试之后&#xff0c;我不得不接受 for&#xff08;倒序&#xff09;是所有 for 循环中最快的这一事实。下面我会举个对一…

2006年互联网七大趋势观察:Web2.0将受挫 [转]

转自&#xff1a;csdn管理频道 原文地址&#xff1a;http://manager.csdn.net/n/20060120/85907.html 趋势观察一&#xff1a;评论搜索 第一个重要趋势就是搜索用户自己产生的内容。2005年称得上是博客搜索引擎之年。互联网领域对于博客信息的挖掘是如此地关注&#xff0c;以…

Linux关机指令

https://www.cnblogs.com/zhangbing12304/p/8185346.html转载于:https://www.cnblogs.com/ranchosevens/p/10699512.html