手写bind
Function.prototype.newBind = function(obj, ...args) {
const that = this;
return function (...args2) {
const arrSum = args.concat(args2);
that.apply(obj, arrNum);
}
}
手写call
Function.prototype.newCall = function(obj, ...args) {
obj.fun = this;
const res = obj.fun(...args);
delete obj.fun;
return res;
}
function Person (a,b,c){
console.log(this.name);
console.log(a,b,c);
}
const egg = {name: 'aaa'}
Person.newCall(egg, 1,3,4)
实现Object.assign
Object.defineProperty(Object, 'assign', {
value: function(target, ...args) {
if (target == null) {
return new TypeError('Cannot convert undefined or null to object');
}
const to = Object(target);
for (let i = 0; i < args.length; i++) {
const nextSource = args[i];
if (nextSource !== null) {
for (const nextKey in nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
enumerable: false,
writable: true,
configurable: true,
})
实现 instanceof
const myInstanceof = (left, right) => {
if (typeof left !== 'object' || left === null) return false;
let proto = Object.getPrototypeOf(left);
while (true) {
if (proto === null) return false;
if (proto === right.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
实现函数珂里化
function add() {
const _args = [...arguments];
function fn() {
_args.push(...arguments);
return fn;
}
fn.toString = function() {
return _args.reduce((sum, cur) => sum + cur);
}
return fn;
}
console.log(add(1)(2))
实现throttle
const throttle = (fn, time) => {
let flag = true;
return function() {
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, arguments);
flag = true;
}, time);
}
}
实现 debounce(防抖)函数
const debounce = (fn, time) => {
let timeout = null;
return function() {
clearTimeout(timeout)
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, time);
}
};
实现 Array.prototype.reduce()
Array.prototype.reduce = function(callback, initialValue) {
if (this == undefined) {
throw new TypeError('this is null or not defined');
}
if (typeof callback !== 'function') {
throw new TypeError(callbackfn + ' is not a function');
}
const O = Object(this);
const len = this.length >>> 0;
let accumulator = initialValue;
let k = 0;
if (accumulator === undefined) {
while (k < len && !(k in O)) {
k++;
}
if (k >= len) {
throw new TypeError('Reduce of empty array with no initial value');
}
accumulator = O[k++];
}
while (k < len) {
if (k in O) {
accumulator = callback.call(undefined, accumulator, O[k], k, O);
}
k++;
}
return accumulator;
}
实现 Array.prototype.map()
Array.prototype.map = function(callback, thisArg) {
if (this == undefined) {
throw new TypeError('this is null or not defined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
const res = [];
const O = Object(this);
const len = O.length >>> 0;
for (let i = 0; i < len; i++) {
if (i in O) {
res[i] = callback.call(thisArg, O[i], i, this);
}
}
return res;
手写Event事件
class Event {
constructor() {
this._cache = {};
}
on(type, callback) {
let fns = (this._cache[type] = this._cache[type] || []);
if (fns.indexOf(callback) === -1) {
fns.push(callback);
}
return this;
}
trigger(type, data) {
let fns = this._cache[type];
if (Array.isArray(fns)) {
fns.forEach((fn) => {
fn(data);
});
}
return this;
}
off(type, callback) {
let fns = this._cache[type];
if (Array.isArray(fns)) {
if (callback) {
let index = fns.indexOf(callback);
if (index !== -1) {
fns.splice(index, 1);
}
} else {
fns.length = 0;
}
}
return this;
}
}
const event = new Event();
event.on('test', (a) => {
console.log(a);
});
event.trigger('test', 'hello world');
event.off('test');
event.trigger('test', 'hello world');
手写Promise
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
class Promise {
constructor(exector) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = value => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn(this.value));
}
}
const reject = reason => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
try {
exector(resolve, reject);
} catch(e) {
reject(e);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function'? onRejected :
reason => { throw new Error(reason instanceof Error ? reason.message : reason) }
const self = this;
return new Promise((resolve, reject) => {
if (self.status === PENDING) {
self.onFulfilledCallbacks.push(() => {
try {
setTimeout(() => {
const result = onFulfilled(self.value);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
} catch(e) {
reject(e);
}
});
self.onRejectedCallbacks.push(() => {
try {
setTimeout(() => {
const result = onRejected(self.reason);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
} catch(e) {
reject(e);
}
})
} else if (self.status === FULFILLED) {
try {
setTimeout(() => {
const result = onFulfilled(self.value);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
});
} catch(e) {
reject(e);
}
} else if (self.status === REJECTED) {
try {
setTimeout(() => {
const result = onRejected(self.reason);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
} catch(e) {
reject(e);
}
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
static resolve(value) {
if (value instanceof Promise) {
return value;
} else {
return new Promise((resolve, reject) => resolve(value));
}
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
}
static all(promiseArr) {
const len = promiseArr.length;
const values = new Array(len);
let count = 0;
return new Promise((resolve, reject) => {
for (let i = 0; i < len; i++) {
Promise.resolve(promiseArr[i]).then(
val => {
values[i] = val;
count++;
if (count === len) resolve(values);
},
err => reject(err),
);
}
})
}
static race(promiseArr) {
return new Promise((resolve, reject) => {
promiseArr.forEach(p => {
Promise.resolve(p).then(
val => resolve(val),
err => reject(err),
)
})
})
}
}