手写代码集合
1、节流和防抖
节流
在 s 秒内即使被触发多次,也只能执行一次。
function throttle(fn, delay){
let flag = true;
return function (...args){
if(!flag){
return;
}
flag = false;
setTimeout(() => {
fn.apply(this, args);
flag = true;
}, delay)
}
}
防抖
s 秒内函数只会被执行一次,如果 s 秒内多次被触发,则以最后一次触发为标准重新计算延迟时间。
function debounce(fn, delay){
let timer;
return function(...args){
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay)
}
}
2、改变this指向的函数
bind
Function.prototype.bind = function (context){
context = context || window;
context.fn = this;
let args = [... arguments].slice(1);
return function func() {
// 判断是否被当做构造函数使用
if(this instanceof func) {
return new context.fn(...args, ...arguments);
}
return context.fn.apply(context,args.concat(...arguments));
}
}
apply
Function.prototype.call = function (context){
context = context || window;
context.fn = this;
let result;
let args = [...arguments].splice(1);
if(arguments[1]){
result = context.fn(...args);
} else {
result = context.fn();
}
delete context.fn;
return result;
}
call
Function.prototype.apply = function (context){
context = context || window;
context.fn = this;
let args = [...arguments].splice(1);
let result = context.fn(...args);
delete context.fn;
return result;
}
3、promise
概念
promise 对象是一个代理对象,被代理的值在 promise 对象创建时可能是未知的,可以为异步操作的成功和失败分别绑定相应的处理方法。 让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。解决了异步回调地狱问题。
状态
1、pending:进行中
2、fulfilled:已成功
3、rejected:失败
只有异步操作才能决定当前的状态,其他操作无法改变。
一旦状态确定,就不会再改变,这时候称为定型 resolved,状态变化情况:pending ——> fulfilled,pending ——> rejected。
实现一个promise
class Promise{
constructor(executor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.resolveCallback = [];
this.rejectCallback = [];
function resolve(value) {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.resolveCallback.forEach(fn => {
fn();
})
}
}
function reject(reason) {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
this.rejectCallback.forEach(fn => {
fn();
})
}
}
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
then(onFulfilled, onRejected){
return new Promise((resolve, reject) => {
if (this.status === 'fulfilled') {
setTimeout(() => {
const x = onFulfilled(