前言
在JavaScript学习过程中,this一直是众多开发者的痛点。不同调用场景下this指向千变万化,经常让人混淆。本篇文章从零出发,全方位拆解this的作用、使用场景、五大绑定规则以及箭头函数的特殊机制,帮你一次性吃透this。
1.什么是this
1.1 基本定义
this 是js中的一个关键字,它提供了一种更优雅的方式隐式的传递一个对象的引用,可以让代码更简洁,易于复用.
2.this的使用场景
2.1 全局作用域中的this
当我们在全局作用域下打印this,会输出什么呢?来看看这一段代码
arduino
console.log(this);
我们以chrome浏览器输出看一下结果:
将它写在全局作用域下,使用 Chrome 浏览器运行,可以看到控制台输出了 window。浏览器全局作用域中的 this指向的就是全局 window 对象。
2.2 函数体内的this
在JS中,函数体内的this是开发的高频使用场景。和全局this不同,函数内的this在定义时无确定指向,仅在调用时才会绑定对应对*。不同的调用方式,this会绑定不同的对象,这也是大家学习this最容易混淆的地方。 为了帮大家系统化判断所有场景下this的指向,接下来我逐一详解五大绑定规则。
3.this五大绑定规则
3.1 默认绑定
定义:当函数独立调用时,函数中的 this 指向window。
知识点:那什么是函数的独立调用呢?若我们有一个foo函数,我们直接调用foo(),这就是独立调用;如果是一个对象里面有foo这个属性并且指向foo函数,你如果像这样调用test.foo(),这就是非独立调用。类似于你的女朋友牵着你逛街就是非独立,你一个人单独逛街就是独立。
为了方便理解,你来看看这个代码,猜猜看this指向谁:
js
var a = 1;
function bar(){
var a = 2;
function foo(){
console.log(this.a);
}
foo();
}
bar();
根据定义我们一眼就可以就可看出 this 指向的是全局的 window ,所以 this.a 会输出1。运行结果如下:

3.2 隐式绑定
定义:当一个函数被一个执行上下文对象所拥有,并被对象调用时,函数中的this会指向该对象。
来看看下面这段代码,猜猜这个时候this指向谁:
js
function foo(){
console.log(this);
}
var obj = {
a: 1,
foo: foo //引用
}
obj.foo();
我们把 obj 比作刘亦菲的直播间,foo 函数就代表你本人。你身处直播间中,直播间的主人拥有主导权。执行 obj.foo(),就好比主播在直播间点名 @你,邀请你担任直播间管理员。一旦接受这份身份,你就归属于直播间主体,对应代码逻辑里,函数内部的 this 便指向了调用它的 obj。
借助这个生活化的比喻,是不是就能轻松判断出此时 this 的指向啦?答案揭晓如下:

3.3 隐式丢失
定义:当一个函数被多层对象调用,函数的 this 指向最近的那个对象。
同样来看看下面这段代码,猜猜这个时候this指向谁:
js
function foo(){
console.log(this.a);
}
var obj = {
a: 1,
foo: foo //引用
}
var oo ={
a: 2,
obj: obj
}
oo.obj.foo();
上面我们把 obj 比作刘亦菲的直播间,那这一次我们把 oo 当成高圆圆的直播间。这时候执行 oo.obj,就相当于刘亦菲走进了高圆圆的直播间 ;而你依然是刘亦菲直播间里的那个管理员(obj.foo)。虽然你现在能看到高圆圆的直播间,但你的身份、归属、管理权本质上还属于刘亦菲的直播间,并不是高圆圆直播间的管理员。对应到代码逻辑里,执行 oo.obj.foo() 时,this 指向的依然是刘亦菲的直播间(obj) 。
有了这样生动的类比,相信大家都能快速分辨 this 的指向。下面为大家揭晓答案:

3.4 显式绑定
简单来说:显示绑定就是可以人为的将this指向obj
3.4.1 call() 方法使用
js
function foo(x,y){
console.log(this.a, x + y);
}
var liu = {
a: 1,
}
foo.call(liu,2,3);
call() 方法的作用就是强制修改函数内部的 this 指向 。这里 foo.call(liu, 2, 3) 直接让 foo 的 this 指向 liu 对象,并把 2、3 作为参数传入执行。代码运行结果如下:

3.4.2 apply() 方法使用
js
function foo(x,y){
console.log(this.a, x + y);
}
var jie = {
a: 2
}
foo.apply(jie);
foo.apply(jie,[2, 3]);
foo.apply(jie,[2, 3, 4]);
apply() 方法和 call() 一样,都可以强制指定函数内部 this 的指向 ,唯一的区别是传参方式 ------call 是逐个传参,而 apply 要求把参数统一放进一个数组里传递。
在这段代码中,foo.apply(jie) 把 foo 的 this 绑定到 jie 对象,但没有传入参数;foo.apply(jie, [2, 3]) 同样将 this 指向 jie,并把数组 [2, 3] 中的元素依次传给 x 和 y;即使传入多余参数的 foo.apply(jie, [2, 3, 4]),apply 也只会取数组前两项对应赋值,不影响核心逻辑。简单说,apply 就是 "指定 this + 数组传参" 的函数调用方式。运行结果如下:

3.4.3 bind() 方法使用
js
function foo(x,y){
console.log(this.a, x + y);
}
var fu = {
a: 3
}
const bar = foo.bind(fu);//const bar = foo.bind(fu, 1, 4);
bar(1, 4);
const bar2 = bar.bind(fu,1);
bar2(4);
const bar3 = bar.bind(fu, 1, 4);
bar2(5);
bind() 方法和 call()、apply() 作用一致,核心都是强制永久绑定函数内部的 this 指向,但它最大的特点是不会立即执行函数,而是返回一个永久绑定了 this 和预设参数的新函数,后续调用新函数即可生效。
这段代码中,foo.bind(fu) 会把 foo 的 this 永久绑定到 fu 对象上,并返回新函数 bar;后续直接执行 bar(1, 4),this 依然指向 fu。同时 bind 支持柯里化传参:可以在绑定时预设部分参数,调用时再传剩余参数,也可以多次绑定,但 this 只会以第一次绑定的对象为准,无法被二次修改 ,无论后续怎么绑定新函数,this 始终指向最初的 fu 对象。运行结果如下:

3.5 new绑定
用通俗的话来讲new的原理会导致函数的 this 指向实例对象。
在写对象一文时针对
new操作符执行步骤的讲解存在疏漏,在此重新为大家梳理new 的完整执行流程
通过代码形式讲解:
js
function Person(){
//var obj = {} //1
// Person.call(obj) //2
this.name = '杰哥'; //3 obj.name= '杰哥'
//obj.__proto__ = Person.prototype; //4
// return obj; //5
}
const p = new Person();
console.log(p);
- JavaScript 会在底层隐式创建一个全新的空对象,作为后续生成实例的基础。
- 将这个空对象的
__proto__属性指向构造函数Person的prototype原型对象。 - 通过
call方法把构造函数内部的this绑定到刚创建的空对象上,让函数内操作都作用于该对象。 - 执行构造函数内部代码。
- 若构造函数没有手动返回引用类型数据,会自动将这个处理完成的新对象返回,最终变量
p便能接收该实例。
4.箭头函数的this
定义:箭头函数没有 this 这个概念,写在箭头函数中的 this 也是它外层那个非箭头函数的。例如以下代码:
js
function foo(){
var fn= () =>{
this.a=2;
}
fn();
}
var obj = {
a: 1,
bar: foo
}
obj.bar();
console.log(obj);
在示例中,foo 函数里定义了箭头函数 fn,fn 内部的 this 继承自 foo 的 this;而 foo 是通过 obj.bar () 调用的,因此 foo 的 this 指向 obj 对象,箭头函数 fn 的 this 也跟着指向 obj。最终 this.a=2 直接修改了 obj 的 a 属性,控制台打印出的 obj 对象中 a 的值为 2。
结果如下:

5.总结
-
this 指向:JavaScript 中 this 是动态绑定的,指向谁不看定义,只看调用方式。
-
全局作用域 this:浏览器环境下,全局 this 指向 window 对象。
-
默认绑定:函数独立调用时,this 指向 window。
-
隐式绑定:函数被对象调用时,this 指向 调用它的对象,遵循 "谁调用指向谁"。
-
隐式丢失:多层对象链式调用时,this 指向 最近一层调用对象,与外层对象无关。
-
显式绑定:通过 call / apply / bind 强制手动修改 this 指向,优先级高于隐式绑定。
-
new 绑定:使用 new 调用构造函数时,this 指向新创建的实例对象。
-
new 执行步骤:创建空对象 → 绑定原型 → 绑定 this → 执行构造代码 → 返回新对象。
-
箭头函数 this:没有自己的 this ,会继承外层作用域的 this,指向无法被修改。
以上就是关于 JS 中
this全部内容啦,知识点梳理得比较全面。如果本文对你有所帮助,欢迎点赞 + 收藏,也可以在评论区留言交流学习心得,我们一起进步!