2023高频面试题,手写apply、call、bind,一文弄懂this指向(在不卷起来就没机会啦)

前言:2023 互联网迎来了行业寒冬,随着ChatGPT发布,主流市场转型,大厂裁员严重的严峻形式下;3年前端、5年前端很难约到自己心仪面试机会,全国各处都散布着前端已死的留言。其实也没那么严重,大部分有工作经验的还是能够很好找到工作的,目前这个行情只是淘汰了很多的初学者。所以我们只需要做好我们自己保持学习,静待花开就行了(注重知识深度)👇👇👇。


一、了解用法之前我们深入了解一下this指向(重要

1.通过new 调用,示例:new method();函数中的this指向新对象

2.直接调用,示例:method(); 函数中的this指向全局对象

3.通过对象调用,示例:obj.method(); 函数中的this指向前面的对象

4. apply、call、bind,示例:method.call(ctx); 函数中的this指向第一个参数

二、我们熟悉一下什么是apply、call以及bind

applycallbind 是JavaScript中用于改变函数上下文环境的三个方法。

apply: 用于将一个数组作为参数传入到被调用的函数中,例: this.fn([1,2]) = fn.apply(this,[1,2])。

call : 用于调用函数,并将函数的参数传入到被调用的函数中,例: this.fn(1,2) = fn.call(this,1,2)。

bind : 作用是将函数绑定到一个指定的对象上,以便在以后更容易调用它。

手写apply:(实现比较简单,但要在面试中脱颖而出比较难,而下面这样写想不拿满分难)
Function.prototype.myApply = function (target,...args){
    //1.判断是否是函数,不是的话抛出错误
    if(typeof(this) !== 'function'){
        throw new TypeError(`${this}.myApply is not a function`)
    };
    //2.检查target是否是null或者undefined;如果是的话指向全局
    const arr= [null,undefined];
    target = arr.includes(target)? globalThis:Object(target);
    //3.利用es6 Symbol语法申明不重复变量
    let key = Symbol('a');
    //4.利用es5 defineProperty语法去掉对象target里面的属性
    Object.defineProperty(target,key,{
        value:this,
        enumerable:false
    })
    let res = target[key](...args)
    delete target[key];
    return res
}
const fn = function(arr){
    console.log(this,arr) // [Number: 0] [ 1, 2 ];
    return arr.reduce((a,b)=>a+b,0) // 3
};
fn.myApply(0,[1,2])
手写call:(call 实现同理,传递的参数有些变化)
Function.prototype.myCall = function(target,...args){
    if(typeof(this) !=='function'){
        throw new TypeError(`${this}.myCall is not a function`);
    };
    const arr = [null,undefined];
    target = arr.includes(target)?globalThis:Object(target);
    const key = Symbol('a');
    Object.defineProperty(target,key,{
        value:this,
        enumerable:false
    });
    const res = target[key](...args);
    delete target[key];
    return res
}
const fn = function(a,b){
  console.log(this,a,b) //{} 1 2
}
fn.myCall({},1,2)
手写bind:
  1. 不使用 apply 和 call 手写

Function.prototype.myBind = function(target){
    let arr = [null,undefined];
    target = arr.includes(target)? globalThis:Object(target);
    let fn = this;
    return function(...args){
         const key = Symbol('a');
         Object.defineProperty(target,key,{
             value:fn,
             enumerable:false
         });
         let res  = target[key](...args);
         delete target[key];
         return res
    } 
}
const fn = function (a,b){
    console.log(this,a,b) // {} 1 2
};
const newFn = fn.myBind({})
newFn(1,2)
  1. 使用apply 手写

Function.prototype.myBind = function(target){
    let arr = [null,undefined];
    target = arr.includes(target)? globalThis:Object(target);
    let fn = this;
    return function(){
          return  fn.apply(target,arguments);
    } 
}
const fn = function (a,b){
    console.log(this,a,b) // {} 1 2
};
const newFn = fn.myBind({})
newFn(1,2)
  1. 使用call 手写

Function.prototype.myBind = function(target){
    let arr = [null,undefined];
    target = arr.includes(target)? globalThis:Object(target);
    let fn = this;
    return function(...args){
         return  fn.call(target,...args);
    } 
}
const fn = function (a,b){
    console.log(this,a,b) // {} 1 2
};
const newFn = fn.myBind({})
newFn(1,2)

好了这一刊就记录到这里,小小 前端在这里祝大家新的一年里都有所收获,顺风顺水。欢迎大家来找我讨论摸鱼之道

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值