「回顾2022,展望2023,我正在参与2022年终总结征文大赛活动」

1. 前语

对于JavaScript开发者来说,this 不熟悉的小伙伴点这里 是一个让咱们头疼的要害字。但当咱们真的学会this这个机制之后,就觉得它是真的香。下面我就来介绍this显现绑定call()、apply()、bind() 三种办法吧。

2. call() 办法

界说: 调用一个目标的办法,以另一个目标换当时目标,可将一个函数的目标上下文从初始的上下文改动为由thisObj 指定的新目标。

语法: Function.call(thisObj, arg1, arg2, ….)

阐明:

  • 如果没供给thisObj参数,则会指向大局Window
  • call承受多个参数为Function的参数,调用后回来Funtion函数的履行成果。

完成call要害因素:

  • 使Funtion 函数的this指向thisObj。
  • 将Funtion 函数履行,一起将后序参数作为funtion的参数,若有回来值则回来。
Function.prototype.my_call = function() {
 if (typeof this !== 'function') { // 优化函数才能够调用`call`
  throw new TypeError('error')
 }
 let obj = arguments[0]
 const args = Array.prototype.slice.call(arguments, 1) // 第一个函数以外的参数
 obj = obj || window  // 避免没传第一个参数
 const fn = Symbol('fn') // 声明 仅有变量 fn
 obj[fn] = this // 改动函数this指向(要害代码)
 const result = obj[fn](...args)  // 调用函数(要害代码)
 delete obj[fn] // 删去 obj 上的 fn 特点
 return result  // 回来函数履行成果
}
var name = 'zhangsan'
var obj = {
 name: 'lisi',
 fn: 123
}
//咱们完成
const res = foo.my_call(obj, 1, 2) 
console.log(res); //  lisi 3 
 // 官方
const res1 = foo.call(obj, 1, 2) //  lisi 3 
console.log(res1); //  lisi 3 

3. apply() 办法

界说: 与call办法相同,但apply第二个参数承受一个数组。

语法: Function.call(thisObj, [arg1, arg2, …])

阐明:

  • 如果没供给thisObj参数,则会指向大局Window
  • apply第二个参数为数组,调用后回来Funtion函数的履行成果。

完成apply要害因素:

  • 使Funtion 函数的this指向thisObj。
  • 将Funtion 函数履行,一起将第二个参数作为Funtion的参数,回来Function的履行成果。
Function.prototype.my_apply = function(obj, args) {
 if (typeof this !== 'function') { // 优化函数才能够调用`apply`
  throw new TypeError('error')
 }
 obj = obj || window  // 避免没传第一个参数
 const fn = Symbol('fn') // 声明 仅有变量 fn
 obj[fn] = this  // 改动函数this指向(要害代码)
 const res = obj[fn](...args)  // 调用函数(要害代码)
 delete obj[fn] // 删去 obj 上的 fn 特点
 return res // 回来函数履行成果
}
var name = 'zhangsan'
var obj = {
 name: 'lisi',
 fn: 123
}
//咱们完成
const res = foo.my_apply(obj, [1, 2]) 
console.log(res); //  lisi 3 
 // 官方
const res1 = foo.aplly(obj, [1, 2]) //  lisi 3 
console.log(res1)  //  lisi 3 

4. bind() 办法

界说: 与call办法相同, 可承受任意参数。

语法: Function.call(thisObj, arg1, arg2, …)

阐明:

  • 如果没供给thisObj参数,则会指向大局Window
  • bind承受任意个参数,调用后回来一个新的绑定函数。

完成bind要害因素:

  • 使Funtion 函数的this指向thisObj。
  • 将Funtion 函数履行,一起其他参数作为Funtion的参数, 回来一个新的绑定函数。
  • 如果 new 了回来的新的绑定的函数,该函数的this需求指向Function函数而不是thisObj。
Function.prototype.my_bind = function(obj) {
 if (typeof this !== 'function') { // 优化函数才能够调用`bind`
  throw new TypeError('error')
 }
 obj = obj || window  // 避免没传第一个参数
 const args = Array.prototype.slice.call(arguments, 1)  // 第一个函数以外的参数
 const _this = this 
 const pro = function() {}
 if (this.prototype) {
  pro.prototype = this.prototype
 }
 const bound = function () { // 声明一个bound函数
  // 判断该函数是否被new
  return _this.apply(  // 掉用 apply 办法改动 this指向
   this instanceof pro ? this : obj, // 判断 bound 函数时候被 new 了  如果 new this 指向foo 反之,指向 obj
   args.concat(Array.prototype.slice.call(arguments))
  )
 }
 bound.prototype = new pro() //  bound 函数的原型承继到了foo的原型  (原型链承继)
 return bound // 回来 bound 函数
}
var name = 'zhangsan'
var obj = {
 name: 'lisi',
 fn: 123
}
function foo(a, b) {
 console.log(this.name, a + b);
 return a + b
}
// 自己完成
const bar = foo.my_bind(obj)
console.log(bar());
let bar1 = new bar(3, 4)
console.log(bar1);
// 官方
const bar2 = foo.bind(obj)
console.log(bar2());
let bar3 = new bar(3, 4)
console.log(bar3);

你会写显示绑定方法吗?

5. 结语

你会写显示绑定方法吗?
在不同的开发环境下,咱们灵活的运用这三种显现绑定办法,能够使咱们的this永久不会丢失。