节流: 重复操作被忽略,直到完成
function throttle (callback, delay, immediate) {
let context, args, timer;
let run = () => {
timer = setTimeout(() =>{
!immediate && callback.apply(context, args);
clearTimeout(timer);
timer = null;
}, delay)
}
return function() {
context = this;
args = arguments;
if (timer) return
!!immediate && callback.apply(context, args);
run()
}
}
防抖: 重复操作重置定时器
function debounce (callback, delay, immediate) {
let timer, context, args;
let run = () => {
timer = setTimeout(() => {
!immediate && callback.apply(context, args);
clearTimeout(timer);
timer = null;
}, delay)
}
return function() {
context = this;
args = arguments;
if (timer) {
clearTimeout(timer);
run()
} else {
!!immediate && callback.apply(context, args);
run();
}
}
}
实现new
/**
* new 的过程
* 1. 创建对象
* 2. 设置原型链
* 3. 绑定this
* 4. 返回对象
*/
function _new () {
const shift = Array.prototype.shift;
const constructor = shift.call(arguments);
if (typeof constructor !== 'function') throw new Error('第一个参数必须为函数')
// 创建对象 + 设置原型链
let obj = Object.create(constructor.prototype);
// 绑定this
let result = constructor.apply(obj, arguments);
// 返回对象
return result instanceof constructor ? result : obj;
}
function Car (name, price) {
this.name = name
this.price = price
}
const car1 = _new(Car, 'Benz', 10000)
const car2 = new Car ('Benz', 10000)
console.log(car1 instanceof Car, car2 instanceof Car)
实现call和apply
Function.prototype._call = function (target) {
const fn = this;
if (typeof fn !== 'function') throw new Error('调用者必须是函数')
const type = typeof target;
// 类型检测
if (type === null || type === void 0) target = globalThis || new Function('return this')()
if (!['object', 'function'].includes(type)) {
const constructor = target.constructor;
// 基本类型数据的处理:
// 获得其构造函数,然后重新实例化成为一个对象类型
// 使得其可以扩展属性
target = new constructor(target)
}
// 推出队首内容,剩余的就是参数
[...arguments].shift()
target.fn = fn;
// 执行函数
let result = target.fn(...arguments)
delete target.fn
// 返回结果
return result
}
Function.prototype._apply = function(target) {
const fn = this;
const type = typeof target;
if (typeof fn !== 'function') throw new Error('调用者需要是函数')
if (type === null || type === void 0) target = globalThis || new Function('return this')()
if (!['object', 'function'].includes(type)) {
const Constructor = target.constructor;
target = new Constructor(target)
}
target.fn = fn;
debugger
const args = arguments[1];
if (!Array.isArray(args)) {
throw new Error('第二个参数请传递数组')
}
const result = target.fn(...args);
delete target.fn;
return result;
}
/**
* 测试
*/
var obj = {
name:'joy',
getName(){
console.log(this); //obj
console.log(this.name); //joy
}
};
var obj2 = {
name: 'sam'
};
obj.getName._apply('sss', [1, 2, 3]) // {name: "sam", getName: ƒ}
// obj.getName() // {name: "joy", getName: ƒ}
obj.getName._call(obj2, 1, 2, 3) // {name: "sam", getName: ƒ}
obj.getName._call(1, 1, 2, 3) // {name: "sam", getName: ƒ}
obj.getName._apply(obj2, 1, 2, 3) // {name: "sam", getName: ƒ}
实现 Promise.all
/**
* @description
* Promise是ES6提供的一种解决异步机制的问题,替代了Generate
* Promise有3种状态:
* pending/fulfilled /rejected
* 实例化时传入的callback内部是同步环境,异步内容会被处理.then 或者 .catch 中执行
*/
const _toString = Object.prototype.toString
/**
* @param {*} promiseArr Promise数组
*/
Promise._all = function(promiseArr) {
// 类型验证
// ES6
// if (!Array.isArray(promiseArr)) throw new Error('param type show be array')
if (_toString.call(promiseArr) !== '[object Array]')
throw new Error('param type show be array')
let results = [];
let count = 0; // 记录被成功处理的promise
let nocount = 0; // 记录被跳过的非promise数据
return new Promise((resolve, reject) => {
promiseArr.forEach((promise, index) => {
// 简单类型验证
if (_toString.call(promise) !== '[object Promise]') {
nocount ++;
return true; // 代替 continue
}
promise.then(res => {
count++;
results[index] = res;
// 两个计数相加 = promiseArr长度,说明 promiseArr 被被处理完了
if ((count + nocount) === promiseArr.length) {
return resolve(results);
}
}, function(err) {
return reject(err);
});
})
});
};
// Testing
let p1 = new Promise((resolve, reject) => {
setTimeout(_ => resolve(1), 0)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(_ => resolve(2), 1000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(_ => resolve(3), 500)
})
let result = Promise._all([1,p1, p2, p3])
result.then(res => console.log(res))
网友评论