前端基础拾遗之JavaScript篇

基本类型

继承实现

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
20
requestAnimationFrame(() => {
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
20
new 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.prototypeFunction.__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
17
function 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
8
arr.slice();
// [0, end]

arr.slice(begin);
// [begin, end]

arr.slice(begin, end);
// [begin, end)
  • shift
    shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

不同 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

前端基础拾遗之JavaScript篇

https://lvdawei.com/post/basic-in-javascript/

Author

David Lv

Posted on

2017-07-01

Updated on

2022-02-20

Licensed under