用这些技巧优化你的代码!
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
TL;DR(太长不看)
见底部;
分解
读完关于“If/else 还是 if?”的讨论后,我想分享一些我喜欢遵循的模式,这些模式可以帮助我保持代码的简洁和清晰,或许对你们中的一些人会有所帮助。
人们很容易固守自己习惯的或从一开始就学习的编码模式/风格。希望这次的挑战能让你看到自己能否进步。
我将通过我最近在做的一篇文章中的例子,带你了解一个典型的场景以及如何清理它。
以下是一些开发者可能会这样编写的代码。
注:本示例使用 ES6 编写代码。
我的代码需要确认主机名是否可用,检查我正在操作的是否是本地主机,如果是,则将 cookie 设置为非安全模式。这是必需的,因为否则 Chrome 和其他一些浏览器将不允许通过标记为安全的本地主机存储 cookie。详情请参见Stack Overflow 中较深层的内容。
let secure;
// Check if window.location.hostname is set.
if (
typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname')
) {
const domain = window.location.hostname;
if (domain == "localhost" || domain == "127.0.0.1") {
secure = false;
} else {
secure = true;
}
} else {
secure = true;
}
export default new Cookie({secure: secure});
现在,有几点你可能马上就会注意到。例如,通过将顶部设置let secure为let secure = true.来删除两个“else”语句。
那么,属性值简写形式如何呢?{secure: secure}现在变成了{secure}。
let secure = true;
// Check if window.location.hostname is set,
if (
typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname')
) {
const domain = window.location.hostname;
if (domain == "localhost" || domain == "127.0.0.1") {
secure = false;
}
}
export default new Cookie({secure});
我们已经做了一些改进,但肯定还可以做得更好。每当你看到子“if”语句时,都应该问问自己“我该如何简化它?”。如果你知道如何避免使用子“if”语句,那么你几乎不需要用到它们。
我们先将子“if”语句提取出来,放在主“if”语句下面。
我们可以通过将上面的“domain”变量初始化为“null”或“false”(我更喜欢null,欢迎讨论),然后如果主机名可通过window.location.hostname获取,则将域名设置为主机名。
接下来,我们更新子程序“if”,除了对 localhost/127.0.0.1 进行原始检查之外,现在还要检查“domain”是否具有真值。
这让我想起来,我们得用正则表达式清理一下对 localhost/127.0.0.1 的检查。domain == "localhost" || domain == "127.0.0.1"现在变成了/^(localhost|127\.0\.0\.1)$/.test(domain)
如果你不喜欢正则表达式,你可以使用vojtechp提供的这个流畅技巧,让代码更易于阅读。
const localDomains = [ 'localhost', '127.0.0.1' ];
const isLocal = domain && localDomains.includes(domain);
或者你可以试试miniscruff提到的更简洁的版本。Set
const localDomains = new Set([ 'localhost', '127.0.0.1' ])
const isLocal = localDomains.has(domain)
如果您想知道为什么在使用变量之前应该先声明它们,请阅读“始终声明局部变量”。
这样,我们就得到了以下结果。
let secure = true;
// Declared domain variable as a let
let domain = null;
// Check if window.location.hostname is set,
if (
typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname')
) {
domain = window.location.hostname;
}
// Moved out and now checks additionally "domain" is set
if (domain && /^(localhost|127\.0\.0\.1)$/.test(domain)) {
secure = false;
}
export default new Cookie({secure});
希望你现在已经开始明白,我们每次都会对代码进行一些改进。
那么我们能把这件事做到什么程度呢?让我们看看还能做些什么。
我编码风格的一个重大改进,是从一个偶然看到的博客上学到的。我真希望能够注明出处,可惜时间太久远了,我已经忘了是谁写的了。
他们展示的是,当涉及两个或多个值时,应该将逻辑从 if 语句中移出并赋值给变量。我之后会专门写一篇文章来详细介绍这方面,因为你可以进行很多创造性的操作,但现在我们先保持简单。
所以我们现在要从
if (
typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname')
)
到
const hostnameAvailable = typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname');
这样做的好处在于,你可以开始清理你的 if 语句,使其更易读,甚至完全摆脱它们(在合理范围内)。
知道了这个新技巧后,我们就带着这个目标继续前进。
如果你仔细观察,你会发现我们是在彼此之间构建“if”语句……所以感觉我们或许可以利用三元运算符。
将我们学到的将“if”逻辑移到变量中的新技巧与三元运算符结合起来,你就可以做到这一点了!
let secure = true;
const hostnameAvailable = typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname');
const domain = hostnameAvailable ? window.location.hostname : null;
const isLocal = domain && domain.match(/localhost|127\.0\.0\.1/);
if (isLocal) {
const secure = false;
}
export default new Cookie({secure});
但是,DeChamp……那个“if”语句!哦对了,我们也可以解决这个问题。利用逻辑非“!”来反转真假。也请看看同一页上的双重逻辑非。
const hostnameAvailable = typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname');
const domain = hostnameAvailable ? window.location.hostname : null;
const isLocal = domain && /^(localhost|127\.0\.0\.1)$/.test(domain);
const secure = !isLocal;
export default new Cookie({secure});
哇,看起来好多了!
包起来
-
我们了解到,在变量顶部声明变量并赋予其值,可以帮助消除“else”语句。
-
拆分子“if”语句。
-
将“if”逻辑移到变量中,然后使用三元运算符,可以使代码更容易阅读和串联。
-
当对单个变量进行多次检查时,正则表达式可以进一步清理数据。
-
使用“非”运算符对布尔值进行翻转。
更多小贴士!
// instead of this
if (foo === 'a') {
bar = 'first';
} else {
bar = 'second';
}
return bar;
// use return to clean it up!
if (foo === 'a') {
return 'first';
}
return 'second';
// instead of this
const foo = bar ? bar : baz;
// do this
const foo = bar || baz;
这条信息由用户Kayis提供。
let secure = true;
try {
secure = !window.location.hostname.match(/localhost|127\.0\.0\.1/);
} catch (e) {}
export default new Cookie({ secure });
请在评论区留下你的答案,我会把它们添加到这里并注明你的贡献!
TL;DR(太长不看)
从
let secure;
// Check if window.location.hostname is set.
if (
typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname')
) {
const domain = window.location.hostname;
if (domain == "localhost" || domain == "127.0.0.1") {
secure = false;
} else {
secure = true;
}
} else {
secure = true;
}
export default new Cookie({secure: secure});
到
const hostnameAvailable = typeof window !== 'undefined'
&& window.hasOwnProperty('location')
&& window.location.hasOwnProperty('hostname');
const domain = hostnameAvailable ? window.location.hostname : null;
const isLocal = domain && /^(localhost|127\.0\.0\.1)$/.test(domain);
const secure = !isLocal;
export default new Cookie({secure});
后续报道
我真心希望你学到了一些新技巧。看着自己的代码变得越来越简洁清晰,真的很有意思。如果我的读者中有人能教我更多技巧,我也不会感到惊讶!
你喜欢我的帖子吗?有什么疑问吗?我有没有遗漏什么或者犯了错误?请告诉我!
——德尚
Varymade LLC。
我们目前的项目是https://charactergenerator4000.com和https://coder.exchange。欢迎访问并告诉我们您的想法。
文章来源:https://dev.to/dechamp/clean-up-your-code-with-这些-tips-4p5f