前端面试题

深入理解bind/call/apply以及手写

2021-05-21  本文已影响0人  前端_酒館

bind/call/apply都是用来重新定义(改变)函数内部的this指向。

例子: 菜鸟的例子更加清晰

var year = 2021
function getDate(month, day) {
    return this.year + '-' + month + '-' + day
}

let obj = {year: 2022}
getDate.call(null, 3, 8)    //2021-3-8
getDate.call(obj, 3, 8)     //2022-3-8
getDate.apply(obj, [6, 8])  //2022-6-8
getDate.bind(obj, 3, 8)()     //2022-3-8

区别:

实现bind/call/apply

Function.prototype.bind = function(context, ...args1) {
  context = (context === undefined || context === null) ? window : context
    let _this = this
  return function(...args2) {
    context.__fn = _this
    let result = context.__fn(...[...args1, ...args2])
    delete context.__fn
    return result
  }
}
Function.prototype.call = function(context, ...args) {
  context = (context === undefined || context === null) ? window : context
    context.__fn = this
  let result = context.__fn(...args)
  delete context.__fn
  return result
}
Function.prototype.apply = function(context, args) {
  context = (context === undefined || context === null) ? window : context
    context.__fn = this
  let result = context.__fn(...args)
  delete context.__fn
  return result
}

调用手写的bind/call/apply: apply和call除了入参不一样,剩下的都一样

let P = {name: '李三'}
function fun(...arg){
  console.log(this.name + '真', ...arg);
}
fun.bind(P, '试试?', '试试就试试')('2222'); //李三真 试试? 试试就试试 2222
fun.bind(P, '试试?', '试试就试试')(); //李三真 试试? 试试就试试
fun.call(P, '试试?', '试试就试试'); //李三真 试试? 试试就试试 
fun.apply(P, ['试试?', '试试就试试']); //李三真 试试? 试试就试试
手写bind/call/apply的输出结果
上一篇下一篇

猜你喜欢

热点阅读