js手写系列

https://www.cnblogs.com/chenwenhao/p/11294541.html

手写curry柯里化

function curry(fn) {
    var length = fn.length //获取原函数的参数数量
    return function result() {
        if (arguments.length < length) {
          //使用bind的用处是将此次的参数带到下一次result的参数里面,且不执行该函数
            return result.bind(null, ...arguments)
        } else {
            return fn(...arguments)
        }
    }
}

function add(a, b) {
    return a + b
}

curry(add)(1)(2) //3

手写bind

Function.prototype.myBind = function(obj, ...args) {
    var self = this
    var fn = function() {
        var _self = this instanceof self ? self : obj
        return fn.apply(_self, args.concat([...arguments]))
    }
    fn.prototype = this.prototype
    return fn
}

function add() {
    console.log(this.name)
}

var obj = {
    name: "obj"
}

add.bind(obj)()

Object.create

function create(prototype){
    function fn(){}
    fn.prototype = prototype
    return new fn()
}

new原理及实现

// 1,创建一个空对象
// 2,链接到构造函数的原型
// 3,绑定this到该对象
// 4,返回新对象

function newF(FN, ...args) {
    var obj = {}
    obj.__proto__ = FN.prototype
    var result = FN.apply(obj, args)
    return typeof result === "object" ? result : obj
}

function Person(name, age) {
    this.name = name
    this.age = age
}

var p = newF(Person, "bobo", 23)


//  使用`Object.create`简化写法
function newF(FN, ...args) {
    var obj = Object.create(FN.prototype)
    var result = FN.apply(obj, args)
    return typeof result === "object" ? result : obj
}

实现apply,call

Function.prototype.newCall = function(obj, ...args) {
    //args此时是数组
    obj.fn = this //在obj上面添加一个函数fn,代表当前函数
    obj.fn(...args) //执行该函数,此时是由obj调用,注意将args展开
    delete obj.fn //然后删除obj.fn
}

Function.prototype.newApply = function(obj, args) {
    // args是数组
    obj.fn = this //在obj上面添加一个函数fn,代表当前函数
    obj.fn(...args) //执行该函数,此时是由obj调用,注意将args展开
    delete obj.fn //然后删除obj.fn
}

var obj = {
    name: "good"
}

function fn(x) {
    console.log(this.name, x)
}

fn.newApply(obj, ["bad"])
fn.newCall(obj, "bad")

Promise

/*
 * 简单版promisee
 * 1,三个状态
 * 2,接收一个函数,有resolve, reject参数
 * 3,定义then
 * 4,then里面的回调函数添加到对应数组中,等待执行
 */
class PromiseB {
    constructor(fn) {
        this.state = "PENDING"
        this.resolvedCallbacks = []
        this.rejectCallbacks = []

        const resolve = res => {
            this.state = "FULFILLED"
            this.internalValue = res
            this.resolvedCallbacks.map(cb => cb(res))
        }
        const reject = err => {
            this.state = "REJECTED"
            this.internalValue = err
            this.rejectCallbacks.map(cb => cb(err))
        }

        try {
            fn(resolve, reject)
        } catch (err) {
            reject(err)
        }
    }

    then(onFulfilled, onRejected) {
        if (this.state === "PENDING") {
            this.resolvedCallbacks.push(onFulfilled)
            this.rejectCallbacks.push(onRejected)
        } else if (this.state === "FULFILLED") {
            onFulfilled(this.internalValue)
        } else if (this.state === "REJECTED") {
            onRejected(this.internalValue)
        }
        return this
    }
}

var a = new Promise((res, rej) => {
    setTimeout(() => res("good"), 1000)
    // resolve("good")
})

promise完善

class newPromise {
    constructor(fn) {
        this.state = "pending"
        this.value = null
        this.resolveCallbacks = []
        this.rejectCallbacks = []

        this.resolve = res => {
            if (this.state === "pending") {
                this.state = "resolved"
                this.value = res
                this.resolveCallbacks.map(cb => cb(this.value))
            }
        }
        this.reject = err => {
            if (this.state === "pending") {
                this.state = "rejected"
                this.value = err
                this.rejectCallbacks.map(cb => cb(this.value))
            }
        }

        try {
            fn(this.resolve, this.reject)
        } catch (err) {
            this.reject(err)
        }
    }

    then(onResolve, onReject) {
        console.log("调用then")
        if (this.state === "pending") {
            return new newPromise((res, rej) => {
                this.resolveCallbacks.push(val => {
                    try {
                        let data = onResolve(val)
                        res(data)
                    } catch (e) {
                        rej(e)
                    }
                })
                this.rejectCallbacks.push(val => {
                    try {
                        let data = onReject(val)
                        res(data)
                    } catch (e) {
                        rej(e)
                    }
                })
            })
        }
        if (this.state === "resolved") {
            return this.resolvePromise(onResolve, this.val)
        }
        if (this.state === "rejected") {
            return this.resolvePromise(onReject, this.val)
        }
    }

    resolvePromise(fn, val) {
        return new newPromise((res, rej) => {
            try {
                let data = fn(val)
                res(data)
            } catch (e) {
                rej(e)
            }
        })
    }
}

newPromise.resolve = function(x) {
    return new newPromise((res, rej) => {
        return res(x)
    })
}

newPromise.reject = function(x) {
    return new newPromise((res, rej) => {
        return rej(x)
    })
}

newPromise.all = function(arr) {
    return new newPromise((res, rej) => {
        var result = []
        var step = 0
        for (let i = 0; i < arr.length; i++) {
            arr[i].then(val => {
                result[i] = val
                step++
                if (step === arr.length) {
                    res(result)
                }
            }, rej)
        }
    })
}

你可能感兴趣的:(js手写系列)