apply & call
call/apply实现原理:让当前的obj(做为this, this是函数被调用的对象)去调用函数
1 | Function.prototype.myCall=function(context){ |
个人粗糙版1
2
3
4
5
6Function.prototype.myCall=function(){
let args = [...arguments]
let caller = args.shift()
caller.func = this
return caller.func(...args)
}
myApply的处理与myCall类似,区别是对参数处理,如果没有参数不能传入空数组,有参数则按参数数组传入1
2
3
4
5
6
7
8Function.prototype.myApply=function(context){
context = context || window
context.fn = this // 调用myCall的函数
let args = [...arguments].slice(1)
let res = args.length>1? context.fn(args): context.fn() // 执行调用myCall的参数,this指向context
delete context.fn // 删除context上的临时属性fn
return res
}
个人粗糙版1
2
3
4
5
6
7Function.prototype.myApply = function(){
let args = [...arguments]
let caller = args.shift()
caller.func = this
let funcArgs = args[0]?args[0]:[]
return caller.func(...funcArgs)
}
bind
bind返回是个新函数,这个函数已经绑定了this作用域,注意这个新函数可以被直接调用或者作为构造函数调用,如果是new调用,则不会被任何方式改变 this,所以对于这种情况我们需要忽略传入的 this。
1 | Function.prototype.myBind = function(context){ |
个人粗糙版1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Function.prototype.myBind = function(context, ...args){
let originalFunc = this
let caller = context
return function f(){
if(this instanceof f){
return new originalFunc(arguments)
}else{
caller.func = originalFunc
return caller.func(...args)
//同上 return originalFunc.apply(caller, args)
}
}
}
防抖
1 | function debounce(fn, wait, immediate) { |
节流
1 | function throttle(fn, wait, immediate) { |
new
- 创建一个空对象obj
- 链接到原型,这个对象的proto指向构造函数的prototype
- 执行构造函数,为这个对象obj增加属性
- 如果构造函数返回了一个对象,则返回这个对象,否则返回obj
1 | function createFactory(){ |
深拷贝
1 | function deepClone(obj){ |
实现一个EventEmitter
1 | class EventEmitter{ |
插入大量dom节点
1 | var maxTimes= 4 |
async await
核心:顺次调用迭代器的next方法,将上一个next的返回值传给下个next作为参数,如果调用结果X.done=true,最后的promise resolve(X.value),否则继续调用next, 中间有异常的话直接抛出1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26function spawn(genF){
return new Promise((resolve, reject)=>{
var iterator = genF()
function step(fn){
let res
try{
res = fn()
}catch(e){
reject(e)
}
if(res.done){
resolve(res.value)
}else{
Promise.resolve(res.value).then(
value => {step(()=>{return iterator.next(value)})},
err => {step(()=>{return iterator.throw(err)})}
)
}
}
step(()=>{return iterator.next(undefined)})// 封装了next方法,这个函数被调用是执行迭代器的next方法
})
}