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)
}
})
}