击剑JavaScript(一)
程序员文章站
2022-03-26 21:49:52
????JavaScript之 call | apply| bind 函数手写以及解释apply函数手写bind函数手写call函数手写话不多说上代码…希望多写博客可以让我收获更多OFFERapply函数手写Function.prototype.applyNew = function(context, args) { context.fn = this; //给context添加一个fn属性,这是一个方法,就是调用apply的函数 console.log(context.fn); let...
话不多说上代码…希望多写博客可以让我收获更多OFFER
apply函数手写
Function.prototype.applyNew = function(context, args) {
context.fn = this; //给context添加一个fn属性,这是一个方法,就是调用apply的函数
console.log(context.fn);
let res;
if(!args) {
context.fn();
}
else {
res = context.fn(...args);
}
return res;
}
let obj = {
name: 'jack'
}
function test(arg1, arg2, arg3) {
console.log(this.name) // jack
console.log(arg1, arg2, arg3); // 1 2 3
}
test.applyNew(obj, [1,2,3]);
我们这样理解,apply
函数就是让context
这个对象去使用调用apply
这个函数的方法,这里是test
。但是我们又需要访问到context
这个对象里面的内容对不?所以怎么办——在context
里面添加一个属性,这个属性是一个方法而且就是这个函数test
。所以我们在context
上添加了一个属性fn
,然后这个属性就是函数test
,也就是this。因为this
就是调用这个函数的上下文。
bind函数手写
Function.prototype.bindNew = function(context, ...args) {
return (...newArgs) => {
this.apply(context,[...args, ...newArgs])
}
}
const test = {
name: "fy",
showName: function (last) {
console.log(this.name + " is " + last);
},
};
test.showName("handsome"); // fy is handsome
test.showName.bind({ name: "Mr.fy" })("handsome");
test.showName.bindNew({ name: "Mr.fy" })("hello");
好像没什么要说的…但是我在写的时候发现return
不能写一个function
而只可以写箭头函数,因为我们后面其实是使用apply
去做到改变this
指向并且执行函数,那么只有使用了箭头函数才可以捕获上下文,只使用function
是不能明确上下文的。但是也可以人为获取上下文比如:
Function.prototype.bindNew = function(context, ...args) {
let self = this;
return function(...newArgs) {
self.apply(context,[...args, ...newArgs])
}
}
const test = {
name: "fy",
showName: function (last) {
console.log(this.name + " is " + last);
},
};
test.showName("handsome"); // fy is handsome
test.showName.bind({ name: "Mr.fy" })("handsome");
test.showName.bindNew({ name: "Mr.fy" })("hello");
这里面首先使用self
去获取上下文this
,然后后面直接使用self
就可以(为什么我更喜欢这种,我感觉这种更清晰更易懂)
call函数手写
Function.prototype.callNew = function(context,...args) {
context.fn = this;
var res = context.fn(...args);
delete context.fn;
return res;
}
let obj = {
name: 'jack'
}
function test(arg1, arg2, arg3) {
console.log(this.name) // jack
console.log(arg1, arg2, arg3); // 1 2 3
}
test.callNew(obj, 1,2,3);
其实call
和apply
很像了,就是参数必须一个一个传,那这样我们就是用...
拓展符就好了。但是要记删除context.fn
,因为,不仅仅是为了释放内存,而且我们使用这些函数的目的就是做到改变上下文,那又为啥要改变人家对象的属性给人家添油加醋(虽然我很喜欢hhhh)
本文地址:https://blog.csdn.net/qq_18998575/article/details/109638051