这是我参与「第四届青训营 」笔记创作活动的的第5天。
如何写好JavaScript(下)
一、写代码最应该关注什么?
- 风格?
- 效率?
- 约定?
- 使用场景?
- 设计?
⭐ 最终写一段好的代码应该从使用场景入手,这样我们才能真正客观地、科学地去评价这段代码的优劣程度。
二、当年的Leftpad事件
❓ Leftpad事件:Leftpad 工具模块被作者从 NPM 上撤下,所有直接或者间接依赖这个模块的 NPM 包全部挂掉了。
原版
function leftpad(str, len, ch) {
str = String(str);
var i = -1;
if (!ch && ch !== 0) ch = ' ';
len = len - str.length;
while (++i < len) {
str = ch + str;
}
return str;
}
优化版
function leftpad(str, len, ch) {
str = "" + str;
const padLen = len - str.length;
if(padLen <= 0) {
return str;
}
return (""+ch).repeat(padLen)+str;
}
⭐ 原版的时间复杂度为,优化版是通过repeat()函数实现的,而repeat()函数采用快速幂的算法,时间复杂度为,因此:
- 代码更简洁
- 效率提升
- 性能更好
三、交通灯状态切换
版本一
code.juejin.cn/pen/7108196… 👉 显而易见,我们不希望看到这样的代码,这样的代码是很难维护的。
版本二(数据抽象)
code.juejin.cn/pen/7108196…
👉 将数据抽象为一个stateList,通过applyState函数递归实现。
版本三(过程抽象)
版本四
四、判断是否是4的幂
版本一
function isPowerOfFour(num) {
num = parseInt(num);
while(num > 1) {
if(num % 4) return false;
num /= 4;
}
return num === 1;
}
👉 当num > 1时,判断num能否被4整除,不能则返回false;最后判断 num是否为1。
版本二
function isPowerOfFour(num) {
num = parseInt(num);
while(num > 1) {
if(num & 0b11) return false;
num >>>=2;
}
return num === 1;
}
👉 对版本一进行优化,使用位运算来判断能否被4整除。
版本三
function isPowerOfFour(num){
num = parseInt(num);
return num > 0 &&
(num & (num - 1)) === 0 &&
(num & 0xAAAAAAAAAAAAA) === 0;
}
👉 时间复杂度为,通过4的幂的二进制数特性直接判断。
版本四
function isPowerOfFour(num) {
num = parseInt(num).toString(2);
return /^1(?:00)*$/.test(num);
}
👉 将num转换为string,利用正则表达式来判断。
五、洗牌
错误写法
code.juejin.cn/pen/7108202… 👉 通过测试,我们发现数字越小的数字越有可能在前面,因此这个写法并不是等可能的。
正确写法
code.juejin.cn/pen/7108203… 👉 每次随机取数,再将数放到数组的最后一位。这样就可以实现等可能。
生成器
code.juejin.cn/pen/7108203… 👉 对正确写法进行修改,可以实现一次选择一张牌。
六、分红包
切西瓜法
code.juejin.cn/pen/7108203… 👉 先对红包金额随机分,每次对较大的部分再分,直至分完;但每个红包金额差异较小;时间复杂度为,空间复杂度为。
抽牌法
code.juejin.cn/pen/7108204… 👉 利用前面所讲的生成器来实现,这样做每个红包金额差异较大,时间复杂度降为,但空间复杂度为;