前言: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
apply、call、bind 是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:
不使用 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)
使用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)
使用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)
好了这一刊就记录到这里,小小 前端在这里祝大家新的一年里都有所收获,顺风顺水。欢迎大家来找我讨论摸鱼之道