实现new操作符
function mynew(Fn, ...args) {
// 1.创建一个新对象
const obj = {};
// 2.新对象原型指向构造函数原型对象
obj.__proto__ = Fn.prototype;
// 3.将构建函数的this指向新对象
const result = Fn.apply(obj, args);
// 4.根据返回值判断
return result instanceof Object ? result : obj;
}
实现bind
Function.prototype.mybind = function (context) {
if (typeof this !== "function") {
throw new TypeError("caller is not a function");
}
const args = [...arguments].slice(1);
const fn = this;
const noop = function () {};
const res = function () {
return fn.apply(this instanceof noop ? this : context || window, [
...args,
...arguments,
]);
};
if (this.prototype) {
noop.prototype = this.prototype;
}
res.prototype = new noop();
return res;
};
科里化
const curry = function (fn) {
return function curriedFn(...args) {
if (args.length < fn.length) {
return function () {
return curriedFn(...[...args, ...arguments]);
};
}
return fn(...args);
};
};
组合函数:将多个函数组合成一个函数
组合函数与管道函数的意义在于:可以把很多小函数组合起来完成更复杂的逻辑
组合函数执行是从右到左的。而管道函数,执行顺序是从左到右执行的
const compose = (...fns) => {
return (val) => {
return fns.reverse().reduce((acc, fn) => {
return fn(acc);
}, val);
};
};
const pipe = (...fns) => {
return (val) => {
return fns.reduce((acc, fn) => {
return fn(acc);
}, val);
};
};
函数缓存
const memoize = function (func, content) {
const cache = Object.create(null);
content = content || this;
return (...key) => {
if (!cache[key]) {
cache[key] = func.apply(content, key);
}
return cache[key];
};
};
精度问题
function strip(num, precision = 12) {
return +parseFloat(num.toPrecision(precision));
}
实现instanceof
const _instanceof = (target, Fn) => {
const type = typeof target;
if ((type !== "object" && type !== "function") || target === null) {
return false;
}
let proto = Object.getPrototypeOf(target);
while (true) {
if (proto === null) return false;
if (proto === Fn.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
};