1. 首页
  2. >
  3. 前端开发
  4. >
  5. Javascript

怎么在javascript中灵活运用 this

this 是什么

Javascriptthis关键词指的是他所属的对象,它拥有不同的值,具体取决于使用的位置和调用方式。

  • 使用方式在方法中,它指向这个方法的拥有者在函数中,它是全局对象window严格模式下在函数中,它是undefined单独使用时,它是全局对象window在事件中,它指向触发事件的目标对象e.target

不同执行模式下的差异化

javascript 中的this不同于其他编程语言,在严格模式和非严格模式下, 它的值是不同的,下面举个例子。

// 非严格模式  function foo() {   return this }  console.log(foo() === window.foo()) //true  // 严格模式 ;('use strict')  function foo() {   return this }  console.log(foo()) // undefined console.log(window.foo()) // window 

非严格模式下foo不论是函数调用还是作为一个方法调用,内部this的指向都是window。 在严格模式下,foo作为一个函数调用时this的值为undefined,而当做window对象的一个方法调用时,它的值指向了调用它的window对象。从代码书写的语义化来看的话,这种this的指向会更合理,这也是javascript的执行环境逐渐向严格模式靠拢的原因,从语言层面抛除一些不符合预期的执行结果。

灵活使用this手动实现函数的callapply

了解了this的诸多特性后我们能利用它实现什么有趣的功能呢?没错,就是下面要手动实现函数的callapply方法。

首先我们需要知道es5call方法实现了什么功能,它的第一个参数是调用函数的this绑定,其余的参数会作为实参传递给执行的函数。了解了这个功能,我们就可以动手去实现它了。

Function.prototype._call = function _call(context, ...args) {   if (context == undefined) {     context = window || global   } else {     context = Object(context)   }   // 获取当前要调用的函数挂载到`context`上    context.handler = this   const result = context.handler(...args)   delete context.handler   return result }  // 测试一下 const value = 10  const foo = {   value: 1, }  function print(arg) {   console.log(this.value)    return arg }  const retVal = print._call(foo, 2) // 1 console.log(retVal) // 2 

为了让_call函数的第一个参数作为this传入到执行函数中去,这里在_call函数内部做了一个变通,把待执行的函数作为context对象的一个方法调用,这样就实现了更改函数调用时this指向的问题。测试后的执行结果也是符合我们的预期的。同理apply函数的实现方式也是如此,只需要把传递的参数处理一下即可,这里就不再演示了。