【JS手写Plan】 篇2

js基础手写第二篇

call

function mycall(context) {
    // 判断它是一个对象 function
    if (typeof this !== 'function') {
        console.log('错误')
    }

    // 获取参数1  slice() 方法可从已有的数组中返回选定的元素。 1 从索引为1的地方开始截取
    let args = [...arguments].slice(1)

    // 定义结果值
    let res = null;

    // context 是否存在
    context = context | window;


    // 将函数作为上下文的一个属性
    context.fn  = this;
    res = context.fn(...args)

    delete context.fn
    return res;
}

apply

function myApply(context) {
    if (typeof this !== "function") {
        console.log.log('error')
    }

    let res = null;

    context = context | window;

    context.fn = this;
    if (arguments[1]) {
        res = context.fn(...arguments[1]);
    } else {
        res = context.fn()
    }
    delete context.fn;
    return res;
}

// 和call差不多,这里就是要注意,判断参数是否传入,并且只去一个

bind

function myBind(context) {
    // 判断thi是否是函数
    if (typeof this !== "function") {
        console.log('error')
    }

    let self = this;
    let args = [...arguments].slice(1);
    let func = function() {
        return self.apply(
            this instanceof func ? this : context ,
            args.concat.apply(...arguments)
        )
    }

    // // 维护原型关系
    // if (this.prototype) {
    //     func.prototype = this.prototype;
    // }

    // // 使得fBound.prototyep是func的实例,返回fBound,若作为new的构造函数,新对象的__proto__就是func的实例
    // fBound.prototype = new func()
    // return fBound
}


ajax

function myAjax(url) {
    let xhr = new XMLHttpRequest();
    xhr.open("GET",url,true);
    xhr.onreadystatechange = function() {
        if (this.readyState !== 4) return;
        
        if (this.status === 200) {
            handle(this.response)
            // handle 是处理这个返回数据
        } else {
            console.log()
        }
    }

    xhr.onerror = function() {
        console.log()
    }

    xhr.responseType = "json";
    xhr.setRequestHeader("Accept", "application/json");
    xhr.send(null)
}

promise (ajax)


// 如果使用这个Promise封装
function myAjax1(url) {
    return new Promise((resolve,reject) => {
        let xhr = new XMLHttpRequest();
        xhr.open("GET",url,true);
        xhr.onreadystatechange = function () {
            if (this.readyState !== 4) return;
            if (this.status === 200) {
                resolve(this.responseText)
            } else {
                reject()
            }
        }

        xhr.onerror = function() {
            reject()
        }

        xhr.setRequestHeader("Accept", "application/json");
        xhr.send(null)
    })
}

sleep

// sleep函数作用是让线程休眠,等到指定时间在重新唤起。
// 使用promise封装
function sleep2 (delay) {
    return new Promise(resolve => {
        setTimeout(resolve, delay)
    })
}

sleep2(1000).then(() => {
    console.log(2000)
})

// 不使用promise封装

function sleep(delay, callback) {
    setTimeout(callback,delay)
}

sleep(100,() => {
    console.log(1000)
})

shallow 浅拷贝

// Object.assign
let jing = {a:1};
let hao = {a:3,b:2};
Object.assign(jing,hao)
console.log(jing) // { a: 3, b: 2 } 会覆盖同名属性


// 扩展运算符
let obj1 = {a:1,c:3};
let obj2 = {...obj1};
console.log(obj2) // { a: 1, c: 3 }

// 数组方法 slice concat


// 手写
function shallowCopy(obj) {
    if (!obj || typeof obj !== "object") return;

    let newobj = Array.isArray(obj) ? [] : {};

    // 指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newobj[key] = obj[key];
        }
    }
    return newobj
}

deep 深拷贝

// JSON.stringify

let obj1 = {
    a:0,
    b: {
        c:0
    }
}

let obj2 = obj1;
let obj3 = Object.assign(obj1) 
let obj4 = JSON.parse(JSON.stringify(obj1)); // 深拷贝 改变值也会改
obj1.a = 1;
obj1.b.c = 1;

console.log(obj1); //{ a: 1, b: { c: 1 } }
console.log(obj2); //{ a: 1, b: { c: 1 } }
console.log(obj3); //{ a: 1, b: { c: 1 } }
console.log(obj4); //{ a: 0, b: { c: 0 } }



// 手写
// 深拷贝的实现
function deepCopy(object) {
    if (!object || typeof object !== "object") return;
  
    let newObject = Array.isArray(object) ? [] : {};
  
    for (let key in object) {
      if (object.hasOwnProperty(key)) {
        newObject[key] =
          typeof object[key] === "object" ? deepCopy(object[key]) : object[key];
      }
    }
  
    return newObject;
  }

curry 柯里化

// 函数柯里化是指一种,将使用多个参数的一个函数,转化成一系列使用一个参数的函数的技术
function curry(fn,...args) {
    return fn.length <= args.length 
    ? fn(...args) 
    : curry.bind(null,fn,...args);
}



function curry1(fn,args) {
    //获取函数需要的参数长度
    let length = fn.length;

    args = args | [];

    return function() {
        // subArgs 加入参数和arguments
        let subArgs = args.slice(0); 

        // 拼接得到现有的所有参数
        for (let i = 0;i < arguments.length;i++) {
            subArgs.push(arguments[i])
        }

        // 判断参数是长度是否满足函数所需要的参数的长度
        if (subArgs.length >= length) {
           return fn.apply(this,subArgs)
        } else {
            // 如果不满足,递归返回柯里的函数,等待参数的传入
            return curry.call(this.fn,subArgs)
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值