- apply
apply函数原理(自定义实现)
Function.prototype.myapply = function (context) {
if (typeof this !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
// this 指函数 printA 将 printA 挂载到传入的变量 a 上去
context.fn = this
let result
if (arguments[1]) {
// 有参数的情况
// 用 a.fn 执行 相当于 a.printA() 执行函数
// 由于 apply 是以数组的形式传递被执行函数的所有参数 所以 arguments[1] 是一个数组
result = context.fn(...arguments[1])
} else {
// 无参的情况 直接执行
result = context.fn()
}
// 最后 把临时 变量 (函数fn) 从 传入的对象(a) 里边删除
delete context.fn
// 返回函数 printA 的执行结果
return result
}
const a={
name:'张三',
age:23
}
function printA(p1,p2){
console.log(this.name)
console.log(this.age)
console.log(p1)
console.log(p2)
}
printA.myapply(a,['p1','p2'])
输出结果
张三
23
p1
p2
- call
call函数原理(自定义实现)
Function.prototype.mycall = function (context) {
if (typeof this !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
context.fn = this
// 由于call对函数参数以变长形式传递,所以可以直接截取从位置1到剩下的arguments数组
let arg = [...arguments].slice(1)
// 将arg解构传递到 printA
let result = context.fn(...arg)
delete context.fn
return result
}
const a={
name:'张三',
age:23
}
function printA(p1,p2){
console.log(this.name)
console.log(this.age)
console.log(p1)
console.log(p2)
}
printA.mycall(a,'p1','p2')
输出结果
张三
23
p1
p2
apply与call的区别
只在参数的传递方式上存在区别
- apply对函数的参数以数组的形式传递
即 fun.apply(obj,[arg1,arg2,...]) apply函数里边的 arguments.length 长度为1或者2 - call对函数的参数以变长参数的形式传递
即 fun.call(obj,arg1,agr2,...) call函数里边的 arguments.length 长度大于等于1
- bind
bind函数原理(自定义实现)
Function.prototype.mybind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
let _this = this
let arg = [...arguments].slice(1)
// bind函数的执行结果返回一个函数,需要自执行才能真正执行 context(即printA)
return function F() {
// 处理函数使用new的情况
if (this instanceof F) {
return new _this(...arg, ...arguments)
} else {
// return _this.apply(context, arg.concat(...arguments))
// 或者
return _this.call(context, ...arg.concat(...arguments))
}
}
}
const a={
name:'张三',
age:23
}
function printA(p1,p2){
console.log(this.name)
console.log(this.age)
console.log(p1)
console.log(p2)
}
printA.mybind(a,'p1','p2')()
输出结果
张三
23
p1
p2
bind基于apply或者call函数实现,函数参数使用可变参数的方式传递
网友评论