
实现 Array.prototype.map
Array.prototype.myMap = function(callback, thisArg) {
if (this == null) {
throw new TypeError('this is null or not defined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
const result = [];
const array = Object(this);
const length = array.length >>> 0;
for (let i = 0; i < length; i++) {
if (i in array) {
result[i] = callback.call(thisArg, array[i], i, array);
}
}
return result;
};
实现 Array.prototype.filter
Array.prototype.myFilter = function(callback, thisArg) {
if (this == null) {
throw new TypeError('this is null or not defined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
const result = [];
const array = Object(this);
const length = array.length >>> 0;
for (let i = 0; i < length; i++) {
if (i in array && callback.call(thisArg, array[i], i, array)) {
result.push(array[i]);
}
}
return result;
};
实现 Array.prototype.reduce
Array.prototype.myReduce = function(callback, initialValue) {
if (this == null) {
throw new TypeError('this is null or not defined');
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
const array = Object(this);
const length = array.length >>> 0;
let accumulator = initialValue;
let i = 0;
if (initialValue === undefined) {
if (length === 0) {
throw new TypeError('Reduce of empty array with no initial value');
}
accumulator = array[0];
i = 1;
}
for (; i < length; i++) {
if (i in array) {
accumulator = callback(accumulator, array[i], i, array);
}
}
return accumulator;
};
实现 Function.prototype.bind
Function.prototype.myBind = function(thisArg, ...boundArgs) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
const originalFunc = this;
return function(...args) {
return originalFunc.apply(thisArg, boundArgs.concat(args));
};
};
实现 Object.create
Object.myCreate = function(proto, propertiesObject) {
if (typeof proto !== 'object' && proto !== null) {
throw new TypeError('Object prototype may only be an Object or null');
}
function F() {}
F.prototype = proto;
const obj = new F();
if (propertiesObject !== undefined) {
Object.defineProperties(obj, propertiesObject);
}
if (proto === null) {
obj.__proto__ = null;
}
return obj;
};
实现 Promise
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (x === promise2) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}