likes
comments
collection
share

理解 this GPT趣味润色 有助于理解版this 是 JavaScript 中动态绑定的复杂概念,指向取决于函数的

作者站长头像
站长
· 阅读数 42

this 是 JavaScript 中出了名的“谜题”,它的指向不是固定的,而是完全取决于函数怎么被调用。要理解这个概念,我们得来个“逐层剥皮”,像剥洋葱一样,搞清楚它在不同场景下的表现。下面我带你看看几个不同的场景,帮你解锁 this 这个让人崩溃的概念。


1. 普通函数中的 this

首先,this 在普通函数中就像个“听话的孩子”,谁叫它它就听谁的,完全取决于谁调用了这个函数。就好像它是个帮工,谁喊它,它就乖乖地站到那个人旁边去。

function showThis() {
  console.log(this);  // 浏览器中是 window,Node.js 中是 global
}
showThis();

看见了吗?showThis 是在全局环境中执行的,this 自然就乖乖听全局对象的命令,在浏览器中它指向 window,在 Node.js 中它指向 global。就好像 this 是个无处不在的服务员,默认为全场服务。

现在,如果我们把它放在对象里,看看它是不是还听话?

javascript


复制代码
const obj = {
    a: 1,
    b: function() {
        console.log(this.a);  // 输出 1
    }
}
obj.b();

瞧瞧,调用 b 的是 objthis 立刻就认主了,乖乖地指向 obj。就像一个对象说:“嘿,this,给我查查我的 a 是多少?” this 马上答:“好嘞大哥,a 是 1!”

但是!如果你打开“严格模式”('use strict'),那就像是跟 this 说:“别傻了,谁也不许指!”于是它就懵了——直接指向 undefined 了。

'use strict';
function showThis() {
  console.log(this);  // 输出 undefined
}
showThis();

嗯,严格模式下 this 就变成“没人能指使我”的小 rebel。


2. 箭头函数中的 this

好,普通函数讲完了,接下来介绍我们的小聪明鬼——箭头函数

普通函数的 this 是谁叫它它听谁的,而箭头函数则完全是“出生决定命运” ,出生的时候就决定了它要跟随谁,这就让它变得特别忠诚,它只认一个“主人”——在它定义时的上下文。

function Outer() {
  this.name = 'outer';

  const regularFunction = function() {
    console.log(this.name);  // 严格模式下是 undefined,非严格模式是 window
  }

  const arrowFunction = () => {
    console.log(this.name);  // 输出 'outer'
  }

  regularFunction();
  arrowFunction();
}

new Outer();

这里你看到,普通函数还在搞“谁叫我我听谁”的套路,搞得 this 一脸迷茫,不知道到底该听谁的,结果只能输出 undefined(严格模式)。但箭头函数就聪明了,它说:“我从一开始就知道 this 是谁,别想让我变!”于是它输出了 outer

再来看看对象中的箭头函数,它依旧是这个逻辑:

const obj = {
  a: 1,
  b: function() {
    const output = () => {
      console.log(this.a);  // 输出 1
    }
    output();
  }
}
obj.b();

这里箭头函数依旧忠诚地跟随 b 函数的 this,所以指向的是 obj.a


3. 显式绑定:callapplybind

上面讲的全都是 this 自动绑定的例子,就像我们说的“隐式绑定”。不过,this 有时候就像个“迷路的孩子”,得我们亲自给它指路。幸好,JavaScript 还提供了显式绑定的方法,我们可以通过 callapplybind 来让 this 知道该往哪儿走。

1. call()apply()

callapply 就像是“立即纠正 this 的路人”,它们会立刻告诉 this 该指向哪里,然后立刻执行函数。

  • call:你可以逐个参数告诉它应该执行什么。
  • apply:把所有参数装进一个数组,批量告诉它。
function greet(greeting, punctuation) {
  console.log(greeting + ', ' + this.name + punctuation);
}

const person = { name: 'Bob' };

greet.apply(person, ['Hi', '.']);  // 输出 "Hi, Bob."
greet.call(person, 'Hello', '!');  // 输出 "Hello, Bob!"

这两个方法就像是“命令 this 马上行动”的好工具。

2. bind()

如果你不想马上执行,而是想给 this 一个“导航仪”让它在将来知道该往哪走,那你就用 bindbind 会返回一个新的函数,这个函数的 this 永远绑定到指定的对象,简直就是给 this 安装了“GPS”,以后它就不会迷路了。

function greet(greeting, punctuation) {
  console.log(greeting + ', ' + this.name + punctuation);
}

const person = { name: 'Charlie' };

const boundGreet = greet.bind(person, 'Hey');

// 调用绑定的函数
boundGreet('!!');  // 输出 "Hey, Charlie!!"

bindthis 永远记得它的主人是谁,还能提前预备一些参数,简直太方便了。


总结

好了,this 这个概念看起来复杂,其实你可以把它想象成一个听话(但偶尔迷路)的孩子。普通函数里,谁叫它它就听谁的;箭头函数里,它一出生就认定了“老大”;而通过 callapplybind,你可以显式地给它指明方向,让它不再迷失。

希望这些例子能帮你解锁 this 的困惑,别再被它绕晕了!相信通过这些搞笑场景的学习,你可以用更轻松的心态掌握 this,让它在你的代码里听话又乖巧!


这下是不是感觉轻松很多了?this 虽然复杂,但掌握它也没那么难。你已经往前迈进了一大步!

以上内容本人提供初稿,由Ai进行有趣的润色 帮助大家理解

转载自:https://juejin.cn/post/7425939768850350120
评论
请登录