数组
1. 实现数组的push方法
Array.prototype.customPush = function (...items){
for (const item of items) {
this[this.length] = item;
}
return this.length;
};
const arr = [1, 2, 3];
arr.customPush(4, 5, 6);
console.log(arr);
2. 实现数组的pop方法
Array.prototype.customPop = function () {
const len = this.length - 1;
const popValue = this[len];
delete this[len];
this.length = len;
return popValue;
};
const arr = [1, 2, 3];
arr.customPop();
console.log(arr);
3. 实现数组的filter方法
Array.prototype.customFilter = function (callback, context) {
if (typeof callback !== "function")
throw new Error("The first parameter must be a function!");
const self = this,
newArr = [];
self.forEach((item, index, self) => {
if (context) {
if (callback.call(context, item, index, self)) newArr.push(item);
} else {
if (callback(item, index, self)) newArr.push(item);
}
});
return newArr;
};
const arr = [1, 6, 3, 5, 4];
const newArr = arr.customFilter(function (item) {
return item <= 3;
});
console.log(newArr);
4. 实现数组的reduce方法
Array.prototype.customReduce = function (fn, initialValue) {
for (let i = 0; i < this.length; i++) {
if (typeof initialValue === "undefined") {
initialValue = fn(this[i], this[i + 1], i + 1, this);
++i;
} else {
initialValue = fn(initialValue, this[i], i, this);
}
}
return initialValue;
};
const arr = [1, 2, 3, 4];
const newArr = arr.customReduce((res, curr) => {
return res + curr;
});
console.log(newArr);
函数
1. 实现函数的bind方法
Function.prototype.customBind = function (obj, ...args) {
if (!isCallable(this)) {
throw new TypeError(
"Function.prototype.bind called on incompatible" + this
);
}
let self = this;
let binder = function (...restArgs) {
if (typeof new.target !== undefined) {
let result = self.apply(this, [...args, ...restArgs]);
if (Object(result) === result) {
return result;
}
return this;
} else {
return self.apply(obj, [...args, ...restArgs]);
}
};
return binder;
};
const info = {
firstName: "charlotte",
lastName: "lai",
};
const printInfo = function (city, country) {
this.city = city;
this.country = country;
console.log(
`I am ${this.firstName} ${this.lastName} from ${city} ${country}`
);
};
let callPrintInfo = printInfo.customBind(info, "xiamen");
let newResult = new callPrintInfo("china");
console.log(newResult);
2. 实现函数的call方法
Function.prototype.customCall = function (context, ...args) {
context = context ? new Object(context) : globalThis;
const fnKey = Symbol()
context[fnKey] = this
const res = context[fnKey](...args)
delete context[fnKey]
return res
};
const info = {
firstName: "charlotte",
lastName: "lai",
};
const printInfo = function (city, country) {
console.log(
`I am ${this.firstName} ${this.lastName} from ${city} ${country}`
);
};
printInfo.customCall(info, 'xiamen', 'china');
3. 实现函数的apply方法
Function.prototype.customApply = function (context, arg) {
context = context ? new Object(context) : globalThis;
const fnKey = Symbol();
context[fnKey] = this;
const res = context[fnKey](...arg);
delete context[fnKey];
return res;
};
const info = {
firstName: "charlotte",
lastName: "lai",
};
const printInfo = function (city, country) {
console.log(
`I am ${this.firstName} ${this.lastName} from ${city} ${country}`
);
};
printInfo.customApply(info, ["xiamen", "china"]);
操作符
- 实现new操作符
function customNew(constructor, ...args) {
const newObj = new Object();
newObj.__proto__ = constructor.prototype;
const res = constructor.call(newObj, ...args);
return res instanceof Object ? res : newObj;
}
function Person(name, age) {
this.name = name;
this.age = age;
}
const person1 = customNew(Person, "lucy", 15);
console.log(person1);
基于发布订阅模式的js事件处理中心
class EventEmitter {
constructor() {
this.subscribers = {};
}
on(eventName, callback) {
const callbacks = this.subscribers[eventName] || [];
callbacks.push(callback);
this.subscribers[eventName] = callbacks;
}
emit(eventName, ...args) {
const callbacks = this.subscribers[eventName] || [];
callbacks.forEach((cb) => cb(...args));
}
off(eventName, callback) {
const callbacks = this.subscribers[eventName] || [];
const filteredCbs = callbacks.filter((cb) => cb !== callback);
this.subscribers[eventName] = filteredCbs;
}
once(eventName, callback) {
const one = (...args) => {
callback(...args)
this.off(eventName, one)
}
this.on(eventName, one)
}
}
const subscribers = new EventEmitter();
subscribers.on("message", function (message) {
console.log(`Message: ${message}`);
});
subscribers.emit("message", "It is going to rain.");
Promise.all()
function myPromiseAll(iterable){
return new Promise((resolve, reject)=>{
const promises = Array.from(iterable)
const result = []
let count = 0
for (let i=0; i < promises.length; i++){
Promise.resolve(promises[i]).then(res => {
result[i] = res;
count++;
if (count === promises.length) {
resolve(result)
}
}).catch(err => reject(err))
}
})
}
function asyncOperation(id, delay) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`Operation ${id} completed after ${delay}ms`);
resolve(id);
}, delay);
});
}
const promises = [
asyncOperation(1, 2000),
asyncOperation(2, 1000),
asyncOperation(3, 1500)
];
myPromiseAll(promises).then(results => {
console.log("All operations completed:", results);
})