instanceof
function myInstanceof(left, right) {
const prototype = right.prototype;
left = left.__proto__;
while (true) {
if (left === null || left === undefined) return false;
if (prototype === left) return true;
left = left.__proto__;
}
}
new
function myNew1(constructor, ...args) {
const obj = Object.create(constructor.prototype);
const result = constructor.apply(obj, args);
return result instanceof Object ? result : obj;
}
function myNew2(constructor, ...args) {
const obj: any = {};
obj.__proto__ = constructor.prototype;
const result = constructor.apply(obj, args);
return result instanceof Object ? result : obj;
}
call
(Function.prototype as any).myCall = function (context, ...args) {
if (typeof this !== "function") {
throw new TypeError("Error");
}
context = context || window;
context._fn_ = this;
const result = context._fn_(...args);
delete context._fn_;
return result;
};
apply
(Function.prototype as any).myApply = function (context, args) {
if (typeof this !== "function") {
throw new TypeError("Error");
}
context = context || window;
context._fn_ = this;
const result = context._fn_(...args);
delete context._fn_;
return result;
};
bind
(Function.prototype as any).myBind = function (context, ...args) {
if (typeof this !== "function") {
throw new TypeError("Error");
}
const _this = this;
return function f() {
if (this instanceof f) {
return new _this(...args, ...arguments);
}
return _this.apply(context, args.concat(...arguments));
};
};
promise
const PENDING = "pending";
const REJECT = "reject";
const RESOLVE = "resolve";
function MyPromise(fn) {
const that = this;
this.value = undefined;
this.status = PENDING;
this.rejectCallBacks = [];
this.resolveCallBacks = [];
function resolve(value) {
if (that.status === PENDING) {
that.status = RESOLVE;
that.value = value;
setTimeout(() => {
that.resolveCallBacks.forEach((cb) => cb(that.value));
}, 0);
}
}
function reject(value) {
if (that.status === PENDING) {
that.status = REJECT;
that.value = value;
setTimeout(() => {
that.rejectCallBacks.forEach((cb) => cb(that.value));
}, 0);
}
}
try {
fn(resolve, reject);
} catch (error) {
reject(error);
}
}
MyPromise.prototype.then = function (resolveCall, rejectCall) {
resolveCall = typeof resolveCall === "function" ? resolveCall : (v) => v;
rejectCall =
typeof rejectCall === "function"
? resolveCall
: (e) => {
throw e;
};
if (this.status === PENDING) {
this.resolveCallBacks.push(resolveCall);
this.rejectCallBacks.push(rejectCall);
}
if (this.status === RESOLVE) {
rejectCall(this.value);
}
if (this.status === RESOLVE) {
rejectCall(this.value);
}
};
Promise.all
function promiseAll(promises: Promise<any>[]) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
reject(new TypeError("参数错误"));
}
const len = promises.length;
const result = new Array(len);
let n = 0;
promises.forEach((promise, i) => {
Promise.resolve(promise)
.then((v) => {
result[i] = v;
if (++n === len) {
resolve(result);
}
})
.catch((e) => {
reject(e);
});
});
});
}
flag
function myFlag(arr: any[], n?: number) {
n = n === undefined ? 1 : n;
return arr.reduce((acc, cur) => {
if (Array.isArray(cur) && n > 1) {
return acc.concat(myFlag(cur, n - 1));
} else {
return acc.concat(cur);
}
}, []);
}
Object.create()
function myCreat(obj) {
function F() {}
F.prototype = obj;
return new F();
}
Ajax
function ajax(url, method, body, headers) {
return new Promise((resolve, reject) => {
const req = new XMLHttpRequest();
req.open(method, url);
for (let key in headers) {
req.setRequestHeader(key, headers[key]);
}
req.onreadystatechange((() => {
if (req.readyState === 4) {
if (req.status >= 200 && req.status <= 300) {
resolve(req.responseText);
} else {
reject(req);
}
}
}) as any);
req.send(body);
});
}
reduce
(Array.prototype as any).myReduce = function (fn, initialValue) {
const arr = this;
if (!Array.isArray(arr)) {
throw new TypeError("not a array");
}
if (typeof fn !== "function") {
throw new TypeError(`${fn} is not a function`);
}
if (arr.length === 0) {
return initialValue;
}
let accumulator, currentValue, currentIndex;
if (initialValue) {
accumulator = initialValue;
currentIndex = 0;
} else {
accumulator = arr[0];
currentIndex = 1;
}
while (currentIndex < arr.length) {
currentValue = arr[currentIndex];
accumulator = fn(accumulator, currentValue, currentIndex, arr);
currentIndex++;
}
return accumulator;
};