基本类型
继承实现
macrotask 和 microtask
事件循环每次只会入栈一个 macrotask ,主线程执行完该任务后又会先检查 microtasks 队列并完成里面的所有任务后再执行 macrotask。
macrotasks: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering
microtasks: process.nextTick, Promises, Object.observe, MutationObserver
https://juejin.im/entry/58d4df3b5c497d0057eb99ff
https://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context#Event Loop
浏览器侧1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20requestAnimationFrame(() => {
console.log(4);
});
new Promise((resolve, reject) => {
console.log(1);
resolve();
})
.then(() => {
console.log(2);
throw new Error("err");
})
.catch(() => {
console.log(3);
});
setTimeout(() => {
console.log(5);
}, 0);
requestIdleCallback(() => {
console.log(6);
});服务端侧,setImmediate 和 setTimeout 触发先后不固定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20new Promise((resolve, reject) => {
console.log(1);
resolve();
})
.then(() => {
console.log(3);
throw new Error("err");
})
.catch(() => {
console.log(4);
});
setImmediate(() => {
console.log(5);
});
setTimeout(() => {
console.log(6);
}, 0);
process.nextTick(() => {
console.log(2);
});原型
Function.prototype
和Function.__proto__
都指向Function.prototype
,这就是鸡和蛋的问题怎么出现的。Object.prototype.__proto__ === null
,说明原型链到Object.prototype
终止。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17function F() {}
let f = new F();
console.log(f.__proto__ === F.prototype);
console.log(F.prototype.constructor === F);
console.log(f.constructor === F);
console.log(F.__proto__ === Function.prototype);
console.log(Function.prototype.constructor === Function);
console.log(F.constructor === Function);
console.log(Function.__proto__ === Function.prototype);
console.log(Function.prototype.constructor === Function);
console.log(f.prototype === undefined);
console.log(F.prototype.__proto__ === Object.prototype);
console.log(Function.prototype.__proto__ === Object.prototype);
console.log(Object.prototype.__proto__ === null);依赖
数组的方法
- slice
slice() 方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象。且原始数组不会被修改。
1
2
3
4
5
6
7
8arr.slice();
// [0, end]
arr.slice(begin);
// [begin, end]
arr.slice(begin, end);
// [begin, end)- shift
shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
- slice
不同 TAB 页下通讯
BroadcastChannel,Chrome54、Firefox38 Support
1
2
3
4
5
6
7
8
9// tab1
const channel = new BroadcastChannel("channel-name");
channel.onmessage = function(e) {
console.log(e);
};
// tab2
const channel = new BroadcastChannel("channel-name");
channel.postMessage("some message");Shared Workers,Chrome、Firefox29 Support
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// work.js
const connections = [];
onconnect = function(e) {
const port = e.ports[0];
connections.push(port);
port.onmessage = function(e) {
connections.forEach(function(connection) {
if (connection !== port) {
connection.postMessage(e.data);
}
});
};
};
// tab1
const worker = new SharedWorker("worker.js");
worker.port.onmessage = function(e) {
console.log(e.data);
};
// tab2
const worker = new SharedWorker("worker.js");
worker.port.postMessage("hello tab1");localStorage
1
2
3
4
5
6
7// tab1
window.onstorage = function(e) {
console.log(e);
};
// tab2
localStorage.setItem("key", "value");window.opener