思路:将传入的对象作为原型
function create(obj) {
function F() { }
F.prototype = obj
return new F()
}
思路:不断地从左边的原型链上去找
function MyInstanceof(left, right) {
let l = Object.getPrototypeOf(left);
let r = right.prototype;
while (1) {
if (!l) return false;
if (l === r) return true;
l = Object.getPrototypeOf(l)
}
}
思路:
function myNew(fn) {
let obj = {};
obj.__proto__ = fn.prototype;
let res = fn.call(obj);
return typeof res === 'object' ? res : obj
}
直接写
function MyPromiseAll(promises) {
return new Promise((resolve, reject) => {
let count = 0;
let res = [];
promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
count++;
res[index] = value;
if (count === promises.length) {
return resolve(res)
}
})
.catch((err) => reject(err))
})
})
}
思路:返回第一个有结果的promise
function MyPromiseRace(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject)
}
})
}
function allsettled(promises) {
return new Promise((resolve, reject) => {
const res = [];
let count = 0;
for (let i = 0; i < promises.length; i++) {
promises[i]
.then((value) => res[i] = { status: 'fulfilled', value })
.reject((reason) => res[i] = { status: 'rejected', reason })
.finally(() => {
count++;
if (count === promises.length) {
resolve(res)
}
})
}
})
}
// 防抖
function debounce(fn, wait) {
let timer = null;
return function (...args) {
const context = this;
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(() => {
fn.apply(context, args);
}, wait)
}
}
// 节流
function throttle(fn, wait) {
let timer = null;
return function (...args) {
const context = this;
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(context, args);
timer = null;
}, wait)
}
}
附加节流和防抖的应用场景:
Function.prototype.myCall = function (context, ...args) {
context = context || window
args = args || []
const key = new Symbol()
context[key] = this
const res = context[key](...args)
delete context[key]
return res
}
Function.prototype.myApply = function (context, args) {
context = context || window
args = args || []
const key = new Symbol()
context[key] = this
const res = context[key](...args)
delete context[key]
return res
}
Function.prototype.myBind = function (context, ...args) {
let self = this
args = args || []
return function (...newargs) {
const key = Symbol()
context[key] = self
const res = context[key](...args, ...newargs)
delete context[key]
return res
}
}
const url = '/server';
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function () {
if (this.readyState !== 4) return;
if (this.status === 200) {
console.log(this.response);
} else {
console.log(this.statusText);
}
}
xhr.onerror = function () {
console.log(this.statusText);
}
xhr.responseType = 'json';
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(null);
function deepClone(obj, map = new WeakMap()) {
if (obj === null || typeof obj !== 'object' || map.has(obj)) {
return obj;
}
map.set(obj, true)
let newObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
function sleep(delay) {
return new Promise(resolve => setTimeout(resolve, delay))
}