当前位置: 首页> 汽车> 时评 > 个人网站源代码html_网上推广工作_哪家网络营销好_专业营销团队外包公司

个人网站源代码html_网上推广工作_哪家网络营销好_专业营销团队外包公司

时间:2025/7/11 7:55:54来源:https://blog.csdn.net/weixin_41092986/article/details/146174389 浏览次数: 0次
个人网站源代码html_网上推广工作_哪家网络营销好_专业营销团队外包公司

✋🏻前言

又到了金三银四的跳槽潮,面试官真的时不时会问到call、apply、bind的相关问题,利用一点碎片化的时间,我整理了如下...

目录

✋🏻前言

call

入参

返回值

底层

apply

入参

返回值

底层 

bind

入参

返回值

底层 

总结


call

call(context, arg1, arg2 ... argn);
入参

context:this的指向,非严格模式下null和undefined会变成window对象,基础数据类型会转化为引用类型

arg1...argn 可选值

返回值

对应函数返回值

function fn11(arg1, arg2) {console.log(arg1, arg2);console.log(this);return "我是return值";
}
const self1 = { x: "1111" };
const res1 = fn11.call(self1, 1, 2, 3);
console.log(res1);

如果是箭头函数,则结果不一样

const fn1 = (arg1, arg2) => {// 箭头函数this指向不同;console.log(arg1, arg2);console.log(this);
};
const self1 = { x: "1111" };
const res1 = fn1.call(self1, 1, 2, 3);
console.log(res1);

 有关于this的指向问题,可以看我这篇文章

JS中的this 归纳了所有可能影响this指向改变的情况,不过这里不是我们讨论的重点,所以接下来我都不使用箭头函数

底层

知道了语法、用法以及表现效果,我们来手写一个call

Function.prototype.myCall = function (context, ...arg) {// ...arg表示不知道有多少参数context = context == null || context === undefined ? window : context;context = changeContext(context);// 定义一个属性_fn存储传入的函数thisconsole.log("myCall中的this:", this);context._fn = this;const result = context._fn(...arg); // 不使用...的话arg是一个数组// 用完删掉,防止污染delete context._fn;return result;
};

context表示this指向,...arg表示的是动态的参数,因为call支持不定个数的参数,所以我们选用它

第一行排除null和undefined的情况

function changeContext(ctx) {if (typeof ctx === "string") {return new String(ctx);} else if (typeof ctx === "number") {return new Number(ctx);} else if (typeof ctx === "boolean") {return new Boolean(ctx);} else if (typeof ctx === "symbol") {return new Symbol(ctx);} else if (typeof ctx === "bigint") {return new BigInt(ctx);} else {return ctx;}
}

第二行将基本数据类型转化为引用数据类型,不然后续也无法属性赋值(这块代码后续都有用到)

这块是console输出

知道了this,于是我们将定义一个内部属性_fn赋值为this,然后执行这个context._fn的方法,传入参数...arg

  • 为什么是...arg:因为是ES6的结构语法,如果是arg的话就是一个数组,无法满足call的第二个参数
  • 为什么不直接用this(...arg):因为这样会导致this的指向改变
Function.prototype.myCall = function (context, ...arg) {// ...arg表示不知道有多少参数context = context == null || context === undefined ? window : context;context = changeContext(context);// 定义一个属性_fn存储传入的函数thisconsole.log("myCall中的this:", this);const result = this(...arg); // 不使用...的话arg是一个数组return result;
};
这边打印的就是window对象了

 所以这边我们需要“中转一下”

接着我们就需要把我们定义的_fn删除(这是一个好习惯)

最后返回函数执行结果result,来看最后的打印吧

apply

apply(context, args);
入参

context:this的指向,非严格模式下null和undefined会变成window对象,基础数据类型会转化为引用类型

args 可选值

返回值

对应函数返回值

function fn2(arg1, arg2) {console.log(arg1, arg2);console.log(this);
}
const self2 = [222];
const res2 = fn2.apply(self2, [1, 2, 3]);
console.log(res2);

apply和call很相似,我们直接来看底层

底层 
Function.prototype.myApply = function (context, arg) {context = context == null || context === undefined ? window : context;context = changeContext(context);// 定义一个属性_fn存储传入的函数thiscontext._fn = this;const result = context._fn(...arg);// 用完删掉,防止污染delete context._fn;return result;
};

可以看到,唯一的改变点就是入参变成了arg,因为传入的arg是一个数组 | 类数组

然后需要注意的是context._fn中的参数还是...arg结构的结果,在前面的使用部分我们也会看到,arg1、arg2分为对应的1,2而不是[1,2],undefined   

所以底层的知识很重要,根据现象知道本质

bind

bind(context, arg1, arg2 ... argn);
入参

context:this的指向,非严格模式下null和undefined会变成window对象,基础数据类型会转化为引用类型

arg1...argn 可选值

返回值

新建一个函数,此函数是原始函数的副本

function fn3(arg1, arg2) {console.log(arg1, arg2);console.log(this);console.log(typeof this);
}
const self3 = 33;
const res3 = fn3.bind(self3, 1, 2, 3);
console.log(res3);
res3();
很明显的看出将基础类型转化成了引用类型
底层 
Function.prototype.myBind = function (context, ...bindArg) {context = context == null || context === undefined ? window : context;context = changeContext(context);const _that = this;return function (...newArg) {// return _that.call(context, ...bindArg, ...newArg);context._fn = _that;const result = context._fn(...[...bindArg, ...newArg]);// 用完删掉,防止污染delete context._fn;return result;};
};

入参方面和call一样,只不过返回值方面需要修改

首先,返回一个方法,方法的参数也是不定的

然后有两种实现效果

  1. 直接使用call方法,然后把context,解构后的bindArg和解构后的newArg传入
  2. 第二种方式和上面call、apply的相同,注意函数调用的入参,需要先合并再解构,最后返回函数执行结果

总结

我们花了一篇博文从基础到使用到底层彻底讲通call、apply、bind的相关内容,期间也不可避免的涉及了箭头函数和this指向问题,相信我把所有能配置到的情况都列出来了


现在,你可以无比自信的和面试侃侃而谈了,因为你比他专业~~

如果觉得有收获,麻烦给个赞和关注。你的鼓励是我写作的动力,大家一起学习一起进步。

关键字:个人网站源代码html_网上推广工作_哪家网络营销好_专业营销团队外包公司

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: