手写实现bind
function fn() {
console.log(this);
// console.log([...arguments]);
}
Function.prototype.bind2 = function (context) {
// 把this保存起来
let self = this;
// 入参保存
const args = [...arguments].slice(1);
// 构建返回函数
const fn2 = function () {
// 入参保存
const innerArgs = [...arguments];
// 如果是作为构造函数 则不重新指定
const tempContext = this instanceof fn2 ? this : context;
return self.apply(tempContext, args.concat(innerArgs));
}
return fn2;
}
// 测试代码
const obj = { name: '110', age: '18' }
fn.prototype.sex = '男';
let person = fn.bind(obj);
let person2 = new person(obj);
// fn.bind2(obj, 1, 2, 3)(119, 20);
console.log(person2.sex);
手写实现new
new 关键字会进行如下的操作:
- 创建一个空的简单 JavaScript 对象(即
{}); - 为步骤 1 新创建的对象添加属性
__proto__,将该属性链接至构造函数的原型对象; - 将步骤 1 新创建的对象作为
this的上下文; - 如果该函数没有返回对象,则返回
this。
function mayNew(Fn) {
// 校验
if (typeof Fn !== 'function') throw new TypeError('this is not a constructor')
// 创建一个空对象
const obj = {};
// 入参
const args = [...arguments].slice(1);
// 为创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象;
obj.__proto__ = Fn.prototype;
// 将创建的对象作为上下文
const res = Fn.call(obj, ...args);
// 返回结果处理
return res ? res : obj;
}
function Fn(name, age) {
this.name = name;
this.age = age
}
Fn.prototype.say = function () {
console.log('Fn.prototype.say')
}
// 测试1
const me = mayNew(Fn, 110, 26);
console.log(me);
me.say();
// 测试2
const me2 = mayNew(Fn, 119, 27);
console.log(me2);
me2.say();
手写一个类型判断函数
function demo(arg) {
// NaN类型判断
if (isNaN(arg)) return 'NaN';
// 数组 对象 null 日期 正则都可以
return Object.prototype.toString.call(arg).slice(8, -1).toLowerCase();
}
手写节流防抖
节流
function throttle(fn, delay) {
// 定义初始时间为0
let t1 = 0;
return function () {
// 函数当前执行时间
const t2 = Date.now();
// 函数执行时间判断
if (t2 - t1 > delay) {
t1 = t2;
// 改变this指向
fn.call(this, ...arguments);
}
}
}
function fn() {
console.log('函数被执行');
}
// 测试
const tFn = throttle(fn, 200);
tFn();
const tt = setInterval(tFn, 100);
setTimeout(() => {
clearInterval(tt);
}, 5000)
防抖
function debounce(fn, delay){
// 定时器ID
let tId;
return function(){
// 每次执行先清除定时器
clearTimeout(tId)
tId = setTimeout(()=>{
fun.call(this, ...arguments)
},delay)
}
}
// 触发时立即执行一次
function debounce2(fn, delay) {
// 定时器ID
let tId;
return function () {
const immediate = !tId;
// 每次执行清除上一次设定的定时器
clearTimeout(tId);
// 重新设定定时器
tId = setTimeout(() => {
tId = null;
if (!immediate) fn.call(this, ...arguments);
}, delay);
// 立即执行
if (immediate) {
fn.call(this, ...arguments);
};
}
}
function fn(arg) {
console.log('函数被执行', arg);
}
// 测试
const tFn = debounce(fn, 500);
tFn(1);
tFn(2);
tFn(3);
const tt = setInterval(() => tFn('z'), 1000);
setTimeout(() => {
clearInterval(tt);
console.log('定时器已被清除');
}, 5000)
手写Promise
class MyPromise {
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.handlers = [];
const resolve = value => {
if (this.state === "pending") {
this.state = "fulfilled";
this.value = value;
this.handlers.forEach(handler => this.executeHandler(handler));
this.handlers = [];
}
};
const reject = reason => {
if (this.state === "pending") {
this.state = "rejected";
this.value = reason;
this.handlers.forEach(handler => this.executeHandler(handler));
this.handlers = [];
}
};
// 拦截 erro
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
// 事件处理
executeHandler(handler) {
const { onFulfilled, onRejected, resolve, reject } = handler;
try {
if (this.state === "fulfilled") {
if (typeof onFulfilled === "function") {
const result = onFulfilled(this.value);
resolve(result);
} else {
resolve(this.value);
}
} else if (this.state === "rejected") {
if (typeof onRejected === "function") {
const result = onRejected(this.value);
resolve(result);
} else {
reject(this.value);
}
}
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
const handler = { onFulfilled, onRejected, resolve, reject };
if (this.state === "pending") {
// 保存回调函数handlers
this.handlers.push(handler);
} else {
this.executeHandler(handler);
}
});
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
static resolve(value) {
return new MyPromise(resolve => resolve(value));
}
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let completedCount = 0;
const processPromise = (index, value) => {
results[index] = value;
completedCount++;
if (completedCount === promises.length) {
resolve(results);
}
};
promises.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise
.then(value => processPromise(index, value))
.catch(reject);
} else {
processPromise(index, promise);
}
});
});
}
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
if (promise instanceof MyPromise) {
promise.then(resolve).catch(reject);
} else {
resolve(promise);
}
});
});
}
}
const promise2 = new MyPromise((resolve, reject) => {
resolve("Promise 2 resolved");
});
promise2
.then(value => {
console.log(value); // 输出: "Promise 2 resolved"
return "Chain value 1";
})
.then(value => {
console.log(value); // 输出: "Chain value 1"
throw new Error("Error occurred");
})
.catch(error => {
console.log(error.message); // 输出: "Error occurred"
return "Chain value 2";
})
.then(value => {
console.log(value); // 输出: "Chain value 2"
});