前言
今天被之前的学弟问到一个问题,面试的过程中有无面试官问过你call
与bind
的原理,并让你手写,答案是当然有的。
工作的这几年自己也做过面试官,作为一个合格的面试官,个人认为有两点
比较重要,第一
需要知道公司需要的技术人员是什么级别,第二
根据需要的级别来判断求职者的回答是否达到标准。所以对于这道题,写不写的出来不是关键,关键是看你的思路是否清晰。
当然如果是一个初级开发甚至中级开发并不知道如何去实现一个call
,但是我觉得也没什么,毕竟在工作中这种东西除了在某些设计上给你提供思路,一般也不会遇到。
自己写一写记录一下。
Call
call做了什么
- 参数
context
,params
- 将
this
指向context
,params
传递给当前调用call的函数 - 函数执行 有一点需要注意的是:call的context不传,或者传递为
null
,统一指向window
实现
Function.prototype.selfCall = function( context, ...params ) { context == null ? context = window : null !/^(object|function)&/.test( typeof context ) ? context = Object(context) : null let _this = this, result = null, UNIQUE_KEY = Symbol('UNIQUE_KEY') context[UNIQUE_KEY] = _this result = context[UNIQUE_KEY](...params) delete context[UNIQUE_KEY] return result } 复制代码
解释一下都操作干了啥:
- 判断context是不是没传,这里偷了个懒,
undefined == null
是true - 判断context是不是引用数据类型的,不是的话转成引用数据类型
- 保留this指向,创建一个 Symbol key,不乱写一个是怕自己定义的与context上的冲突
- 把当前函数放到context中,即改变等会函数执行的this指向
- 执行函数,注意📢,这里函数执行是通过
context.UNIQUE_KEY()
执行的,也就是函数的this指向context,拿到结果 - 返回结果
bind
bind比call多一个不立即执行
Function.prototype.selfBind = function( context, ...outParams ) { let _this = this return function(...innerParams) { _this.selfCall( context, ...outParams.concat(...innerParams )) } }