Native js

Implement instanceof

1
2
3
4
5
6
7
8
9
10
11
function myInstanceOf(left, right) {
if(typeof left !== 'object' || typeof left === null) return false;
let protp = Object.getPrototypeOf(left);
while(true) {
if(protp === null) return false;
if(protp === right.prototype) return true;
prop = Object.getPrototypeOf(prop);
}
}
console.log(myInstanceOf('aa', String)) // false
console.log(myInstanceOf(new String('aa'), String)) // true

deepCopy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const isObj = (target) => {(typeof target === 'object' || typeof target === 'function') && target !== null};

const deepCopy = (target, map = new Map()) => {
if(map.get(target)) {
return target;
}

if(isObj(target)) {
map.set(target, true);
const cloneTarget = Array.isArray(target) ? [] : {};
for(let prop of target) {
if(target.hasOwnProperty(prop)) {
cloneTarget[prop] = deepCopy(target[prop], map)
}
}
} else {
return target;
}
}

const a = {val:2};
a.target = a;
let newA = deepCopy(a);
console.log(newA)//{ val: 2, target: { val: 2, target: [Circular] } }

forEach 中用 await 问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function handle(x) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(x)
}, 1000*x)
})
}

async function test() {
var arr = [4,2,1];
arr.forEach(async item => {
const res = await handle(item);
console.log(res)
})
}
test()

期望结果是:

1
2
3
4
2
1

实际结果是:

1
2
3
1
2
4

**foreach底层实现

1
2
3
4
5
6
7
// 核心逻辑
for (var i = 0; i < length; i++) {
if (i in array) {
var element = array[i];
callback(element, i, array);
}
}

可以看到,forEach 拿过来直接执行了,这就导致它无法保证异步任务的执行顺序。比如后面的任务用时短,那么就又可能抢在前面的任务之前执行。
解决方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function handle(x) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(x)
}, 1000*x)
})
}

async function test() {
var arr = [4,2,1];
for(const item of arr) {
const res = await handle(item);
console.log(res)
}
}
test()

解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
let arr = [4, 2, 1];
// 这就是迭代器
let iterator = arr[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());


// {value: 4, done: false}
// {value: 2, done: false}
// {value: 1, done: false}
// {value: undefined, done: true}

所以可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
async function test() {
let arr = [4, 2, 1]
let iterator = arr[Symbol.iterator]();
let res = iterator.next();
while(!res.done) {
let value = res.value;
console.log(value);
await handle(value);
res = iterater.next();
}
console.log('结束')
}
// 4
// 2
// 1
// 结束

for … of 就是上面代码的语法糖

Author: Rick
Link: https://rcrick.github.io/2020/03/19/Native-js/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶