手写原生方法
手写原生方法
代码实现 JavaScript 系列
手写实现 call
call
主要都做了些什么?
call()
方法使用一个指定的 this
值和单独给出的一个或多个参数来调用一个函数。
分析:
- 更改
this
指向 - 函数立刻执行
function.call(thisArg, arg1, arg2, ...)
参数:
thisArg
可选的。在
function
函数运行时使用的this
值。请注意,this
可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null
或undefined
时会自动替换为指向全局对象,原始值会被包装。arg1, arg2, ...
指定的参数列表。
返回值:
使用调用者提供的 this
值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined
。
代码实现:
Function.prototype.myCall = function (context) {
// 判断有没有传入要绑定的对象,没有默认是window
// 如果是基本类型的话通过Object()方法进行转换
// 使用 var 重新定义函数局部变量
var context = Object(context) || window
context.fn = this
// 保存返回值
let result = ''
// 取出传递的参数 第一个参数是this, 下面是三种截取除第一个参数之外剩余参数的方法
// 通过...展开运算符将伪数组 argument是转换伪数组,使用数组方法返回参数数组
const args = [...arguments].slice(1)
// 执行方法
result = context.fn(...args)
// 删除绑定,不删除会一直绑fn
delete context.fn
// 返回函数执行结果
return result
}
//test
const a = [1, 2]
console.log(Object.prototype.toString.call(a))
console.log(Object.prototype.toString.myCall(a))
手写实现 apply
实现了call 其实也就间接实现了apply,只不过就是传递的参数不同
Function.prototype.myApply = function (context, args) {
var context = Object(context) || window
context.fn = this
let result = ''
// 判断有没有传入 args
if (!args) {
result = context.fn()
} else {
result = context.fn(...args)
}
delete context.fn
return result
}
手写实现 bind
bind
特性:
- 指定this
- 返回一个函数
- 传递参数并柯里化
Function.prototype.myBind = function(ctx, ...args) {
return (...innerArgs) => this.call(ctx, ...args, ...innerArgs);
};
手写实现 Promise
简单实现一个 Promise 类
function MyPromise(executor) {
// 初始化 state 为等待态
this.state = 'peding'
// 成功的值
this.value = undefined
// 失败的原因
this.reason = undefined
let resolve = value => {
if (this.state === 'pending') {
// resolve调用后,state转化为成功态
this.state = 'fulfilled'
// 储存成功的值
this.value = value
}
}
let reject = reason => {
// state改变,reject调用就会失败
if (this.state === 'pending') {
// reject调用后,state转化为失败态
this.state = 'rejected'
// 储存失败的原因
this.reason = reason
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
Promise all 方法
// Promise.all
// Promise.all 需要等到所有的 promise 的状态都变成 fulfilled 之后才 resolve, 但只要有一个 promise 失败即返回失败的结果。
MyPromise.all = function (arr) {
return new Promise((resolve, reject) => {
if (Array.isArray(arr)) {
throw new Error(`argument must be a array`)
}
let dataArr = []
let num = 0
for (let i = 0; i < arr.length; i++) {
let p = arr[i]
p.then(data => {
dataArr.push(data)
num++
if (num === arr.length) {
return resolve(data)
}
}).catch(e => {
return reject(e)
})
}
})
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!