理解 this GPT趣味润色 有助于理解版this 是 JavaScript 中动态绑定的复杂概念,指向取决于函数的
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
的是 obj
,this
立刻就认主了,乖乖地指向 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. 显式绑定:call
、apply
和 bind
上面讲的全都是 this
自动绑定的例子,就像我们说的“隐式绑定”。不过,this
有时候就像个“迷路的孩子”,得我们亲自给它指路。幸好,JavaScript 还提供了显式绑定的方法,我们可以通过 call
、apply
和 bind
来让 this
知道该往哪儿走。
1. call()
和 apply()
call
和 apply
就像是“立即纠正 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
一个“导航仪”让它在将来知道该往哪走,那你就用 bind
。bind
会返回一个新的函数,这个函数的 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!!"
bind
让 this
永远记得它的主人是谁,还能提前预备一些参数,简直太方便了。
总结
好了,this
这个概念看起来复杂,其实你可以把它想象成一个听话(但偶尔迷路)的孩子。普通函数里,谁叫它它就听谁的;箭头函数里,它一出生就认定了“老大”;而通过 call
、apply
和 bind
,你可以显式地给它指明方向,让它不再迷失。
希望这些例子能帮你解锁 this
的困惑,别再被它绕晕了!相信通过这些搞笑场景的学习,你可以用更轻松的心态掌握 this
,让它在你的代码里听话又乖巧!
这下是不是感觉轻松很多了?this
虽然复杂,但掌握它也没那么难。你已经往前迈进了一大步!
以上内容本人提供初稿,由Ai进行有趣的润色 帮助大家理解
转载自:https://juejin.cn/post/7425939768850350120