手写实现js内置函数,无敌简单的写法一看就会

本文详细介绍了如何手写JavaScript中的call、create、instanceof、new、防抖、节流、深拷贝、Promise、bind和push等常用内置函数,通过实例代码解析其工作原理,帮助你更好地理解和运用这些功能。
摘要由CSDN通过智能技术生成

手写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
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值