对于奇舞团的成员,月影要求我们的代码要优雅一点、更优雅一点,最好是令人惊叹的😂
数组去重
写法零, ES6 Set + filter,常用思路
arrayUnique : (arr) => {
let s = new Set();
return arr.filter(function(o){
if(s.has(o)){
return false
}
else{
s.add(o);
return true
}
});
}
写法一,最"low"版,indexOf
function arrayUnique(arr){
const ret = []
for(let i = 0; i < arr.length; i++){
const item = arr[i],
idx = ret.indexOf(item)
if(idx < 0)
ret.push(item)
}
return ret
}
const arr = [1,3,1,2,2,4,3,4,1]
console.log(arrayUnique(arr))
写法二,利用Object的key的唯一性
function arrayUnique(arr){
const map = {}, ret = []
for(let i = 0; i < arr.length; i++){
const item = arr[i]
if(map[item] == null){
map[item] = i
ret.push(item)
}
}
return ret
}
const arr = [1,3,1,2,2,4,3,4,1]
console.log(arrayUnique(arr))
写法三,利用filter + index
function arrayUnique(arr){
return arr.filter((item,i) => arr.indexOf(item) === i)
}
const arr = [1,3,1,2,2,4,3,4,1]
console.log(arrayUnique(arr))
写法四,纯Set,最史上最简单的数组去重
function arrayUnique(arr){
return [...new Set(arr)]
}
const arr = [1,3,1,2,2,4,3,4,1]
console.log(arrayUnique(arr))
月大大感言:我们要熟悉API
for in 神坑
猜下下面代码输出什么:
var scores = [10,11,12]
var total = 0
for(var score in scores){
total += score
}
var mean = total/scores.length
console.log("mean:",mean)
竟然是4!
当然了,把每一步console出来就知道为什么了。
score是一个字符串,每一步total都是作为字符串去拼接,但最后又变成了number去相除。
另外,for in
会把自定义在prototype上的属性打印出来,所以用for in的时候要在 defineProperty
的时候enumerable
设置为false,或是用hasOwnProperty
判断一下;或者,用for of
:
Array.prototype.contains = function(item){
return this.indexOf(item) >= 0
}
const arr = [1,2,3,4]
for(let key in arr){
console.log(key)
}
for(let [key,value] of Object.entries(arr)){
console.log(key)
}
异步的改良
交通灯。
头大的写法:
function main(){
setTimeout(() => {
traffic.className = 'pass'
setTimeout(() => {
traffic.className = 'wait'
setTimeout(() => {
traffic.className = 'stop'
main()
},1500)
},3000)
},3000)
}
main()
然后我们有了promise:
function wait(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
function main(){
traffic.className = 'stop'
wait(3000).then(() => {
traffic.className = 'pass'
return wait(3000)
}).then(() => {
traffic.className = 'wait'
return wait(1500)
}).then(main)
}
main()
但是我们还有更牛X的async/await:
function wait(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}
async function main() {
//no protect
while(true){
traffic.className = 'stop'
await wait(3000)
traffic.className = 'pass'
await wait(3000)
traffic.className = 'wait'
await wait(1500)
}
}
main()
创建数组,生成0~51
小萌新写法
function generateCards(n){
const ret = []
for(let i=0; i<n; i++){
ret.push(i)
}
return ret
}
let cards = generateCards(52)
console.log(cards)
老油条写法
function generateCards(n){
return Array.from({length:n}).map((_, i) => i)
}
let cards = generateCards(52)
console.log(cards)
为什么不能直接用Array.from(52)?
只new一个52的array,是empty的,无法用map遍历。但是用
Array.from({length:52})
,生成的是52个empty,可以遍历出来:但是显然还有更好的办法,也就是黑山老妖们写出来的:
function *$cards(n = 52){
for(let i = 0; i < n; i++)
yield i
}
let cards = [...$cards]
console.log(cards)
Array构造函数的二义性
const a = new Array(10),
b = new Array(10,9),
c = new Array(10,9,8)
console.log(a,b,c)
可以用Array.of
const a = new Array(10),
b = new Array(10, 9),
c = new Array(10, 9, 8)
console.log(a, b, c)
const d = Array.of(10),
e = Array.of(10, 9),
f = Array.of(10, 9, 8)
console.log(d, e, f)
空/稀疏数组的遍历
Array.from、fill
未完,待续。。。