手写call
Object.defineProperty(Function.prototype,’$call’,{
configurable:true,
enumerable:false,
writable:true,
value:function(obj,…arg){
obj[Symbol.for(‘x’)]=this
let c=obj [Symbol.for(‘x’) ] (…arg)
delete obj[Symbol.for(‘x’)]
return c
}
})
手写create
function $create(obj){
function F(){}
if(typeof obj===object){
F.prototype=obj
}
return new F()
}
手写instanceof
function $instanceof(obj,fn){
let objProto=Object.getPrototypeOf(obj)
let fnProto=fn.prototype
while(true){
if(objProto===fnProto) return true
if(objProto!==fnProto&&objProto === null) return false
objProto=Object.getPrototypeOf(objProto)
}
}
手写new
function $new(fn,…aqm){
let fnProto=fn.prototype
let obj=Object.create(fnProto)
fn.call(obj,…aqm)
return obj
}
手写防抖
((nums)=>{
let trime;
return function(){
if(trime)clearTimeout(trime)
trime=setTimeout(()=>{
console.log(1)
},nums)
}
})(100)
手写节流
((nums)=>{
let trime;
return function(){
if(!trime){
trime=setTimeout(()=>{
console.log(1)
trime=null
},nums)
}
}
})(100)
手写深拷贝
function $clonedeep(obj){
let _obj=Array.isArray(obj)?[]:Object.prototype.toString.call(obj)===’[object Object]’?{}:obj
for(let key in obj){
if(Array.isArray(obj) || Object.prototype.toString.call(obj) === ‘[object Object]’){
_obj[key] = $clonedeep(obj[key])
}else{
_obj[key]=obj[key]
}
}
return _obj
}
promise实现
// 先声明好状态,比较直观明了
const PENNDING = ‘pending’;
const FULFILLED = ‘fulfilled’;
const REJECTED = ‘rejected’;
class MyPromise {
constructor(fn) {
// 添加两个变量用来存储成功和失败的回调
this.FULFILLED_CALLBACK_LIST = [];
this.REJECTED_CALLBACK_LIST = [];
// 新添加 _status 变量是用来返回 status的值,不然get时返回自己容易死循环
this._status = PENNDING;
// 初始状态为pending
this.status = PENNDING;
// 成功之后的值
this.value = null;
// 失败之后的原因
this.reason = null;
// fn函数里面也可能直接执行 throw
// 这里用 try catch 防他一手
try {
// 传入this是为了指向当前上下文
fn(this.resolve.bind(this), this.reject.bind(this));
} catch(e) {
// catch 里面就直接reject
this.reject(e);
}
}
// 添加 status 的get和set方法,主要用于状态变化后的回调执行
get status() {
return this._status
}
set status(newStatus) {
// 存储变化后的status,用于get返回
this._status = newStatus;
// 判断状态,直接执行成功或失败的回调
switch(newStatus) {
case FULFILLED: {
this.FULFILLED_CALLBACK_LIST.forEach( callback => {
callback(this.value);
})
break;
}
case REJECTED: {
this.REJECTED_CALLBACK_LIST.forEach( callback => {
callback(this.reason);
})
break;
}
}
}
resolve(value) {
// 只有pending状态才可以变成resolve
if(this.status === PENNDING) {
// 保存成功的值
this.value = value;
this.status = FULFILLED;
}
}
reject(reason) {
// 只有pending状态才可以变成reject
if(this.status === PENNDING) {
// 保存失败的原因
this.reason = reason;
this.status = REJECTED;
}
}
then(onFulfilled, onRejected) {
// 必须是函数类型,如果不是函数,应该直接返回 value
const realOnFulfilled = this.isFunction(onFulfilled) ? onFulfilled : value => {
return value
}
// 必须是函数类型,如果不是函数,应该直接返回 reason
const realOnRejected = this.isFunction(onRejected) ? onRejected : reason => {
throw reason;
};
const promise2 = new MyPromise((resolve, reject) => {
const fulfilledMicrotask = () => {
// onFulfilled 应该是微任务,等待 promise2 初始化完成
queueMicrotask(() => {
try {
// 正常执行,调用 resolvePromise
const x = realOnFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (e) {
// 执行出错抛出异常,直接 reject
reject(e)
}
})
};
const rejectedMicrotask = () => {
// onRejected 应该是微任务,等待 promise2 初始化完成
queueMicrotask(() => {
try {
// 正常执行,调用 resolvePromise
const x = realOnRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (e) {
// 执行出错抛出异常,直接 reject
reject(e);
}
})
}
// 判断状态进行回调
switch (this.status) {
case FULFILLED: {
// 调用成功的回调,并返回成功的值
realOnFulfilled(this.value);
break;
}
case REJECTED: {
// 调用失败的回调,并返回失败的原因
realOnRejected(this.reason);
break;
}
case PENDING: {
// 在promise还是pending时,不应该被调用成功或失败的回调
// 所以先存起来,等状态改变时再去执行
this.FULFILLED_CALLBACK_LIST.push(fulfilledMicrotask)
this.REJECTED_CALLBACK_LIST.push(rejectedMicrotask)
}
}
})
// 返回一个promise
return promise2
}
catch (onRejected) {
// 直接 .then
return this.then(null, onRejected);
}
resolvePromise(promise2, x, resolve, reject) {
// 如果相等了,说明return的是自己,为了防止死循环就抛出错误
if(promise2 === x) {
return reject(new TypeError("The promise and the return value are the same"));
}
if (x instanceof MyPromise) {
// 如果 x 为 Promise ,则使 newPromise 接受 x 的状态
// 也就是继续执行x,如果执行的时候拿到一个y,还要继续解析y
queueMicrotask(() => {
x.then((y) => {
this.resolvePromise(promise2, y, resolve, reject);
}, reject);
})
} else if (typeof x === 'object' || this.isFunction(x)) {
// 如果 x 为对象或者函数
if (x === null) {
// null也会被判断为对象
return resolve(x);
}
let then = null;
try {
// 把 x.then 赋值给 then
then = x.then;
} catch (error) {
// 如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise
return reject(error);
}
// 如果 then 是函数
if (this.isFunction(then)) {
let called = false;
// 将 x 作为函数的作用域 this 调用
// 传递两个回调函数作为参数
// 第一个参数叫做 resolvePromise ,第二个参数叫做 rejectPromise
try {
then.call(
x,
// 如果 resolvePromise 以值 y 为参数被调用,则运行 resolvePromise
(y) => {
// 需要有一个变量called来保证只调用一次.
if (called) return;
called = true;
this.resolvePromise(promise2, y, resolve, reject);
},
// 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise
(r) => {
if (called) return;
called = true;
reject(r);
});
} catch (error) {
// 如果调用 then 方法抛出了异常 e:
if (called) return;
// 否则以 e 为据因拒绝 promise
reject(error);
}
} else {
// 如果 then 不是函数,以 x 为参数执行 promise
resolve(x);
}
} else {
// 如果 x 不为对象或者函数,以 x 为参数执行 promise
resolve(x);
}
}
static resolve(value) {
// 静态 resolve 是将现有对象转为 Promise 对象
// 所以如果传入的是一个 Promise 就直接返回
if (value instanceof MyPromise) {
return value;
}
return new MyPromise((resolve) => {
resolve(value);
});
}
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
}
手写bind
Function.prototype.$bind=function(obj,…arg){
let that=this
return function (…args){
let c=that(…arg,…args)
that=null
return c
}
}
手写push
Array.prototype.$push=function(){
let a=arguments
let b=this.length
for(let k in a){
this[b++]=a[k]
}
return this.length
}