JS中this指向问题你能完全理解吗?

2026-03-31 14:211阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1502个文字,预计阅读时间需要7分钟。

JS中this指向问题你能完全理解吗?

您能理解JavaScript中`this`指向的问题吗?下面这篇文章将带大家聊聊让人头疼的`this`指向问题,希望对大家有所帮助!

`this`的指向

在JavaScript中,`this`是一个关键字,它指向函数或方法被调用时的上下文对象。在不同的场景下,`this`的指向可能会有所不同。

以下是我们常见的几种`this`指向情况:

1. 作为对象的方法调用:当`this`作为对象的方法被调用时,它指向该对象。 javascript const obj={ name: '张三', sayName: function() { console.log(this.name); } }; obj.sayName(); // 输出:张三

JS中this指向问题你能完全理解吗?

2. 作为普通函数调用:当`this`作为普通函数被调用时,它指向全局对象(在浏览器中是`window`,在Node.js中是`global`)。 javascript function sayName() { console.log(this.name); } sayName(); // 输出:undefined(在浏览器中)

3. 构造函数调用:当使用`new`关键字调用函数时,`this`指向新创建的对象。 javascript function Person(name) { this.name=name; } const person=new Person('李四'); console.log(person.name); // 输出:李四

4. 箭头函数:箭头函数不绑定自己的`this`,它会捕获其所在上下文的`this`值。 javascript const obj={ name: '王五', sayName: ()=> { console.log(this.name); } }; obj.sayName(); // 输出:王五

判断`this`的指向方法

1. 函数调用方式:根据函数的调用方式,可以初步判断`this`的指向。

2.使用`console.log(this)`:在函数内部直接使用`console.log(this)`可以查看当前`this`的指向。

3.使用`Function.prototype.call`或`Function.prototype.apply`:这两个方法可以改变函数的执行上下文,从而改变`this`的指向。

`this`的最终指向

`this`的最终指向取决于函数的调用方式。在函数被调用时,`this`会根据调用方式确定其指向的上下文对象。

你能搞懂JavaScript的this指向问题吗?下面本篇文章带大家聊聊这令人烦恼的this指向问题,希望对大家有所帮助!

this的指向

在我们看见的各种介绍如何判断this的指向方法中,"this的最终指向的是那个调用它的对象" 这句话被视作核心,但是面对多种多样的情况,我们容易搞混。针对针对多种情况结合我的理解,我提出了一句话 “箭头,定时和构造,特殊情况特殊看,普通调用看点号,后面有点不看前,然后就近原则判,最后剩下就是window”

箭头函数

箭头函数的本身没有this,所有不存在this改变,它捕获外层的this使用

var name = "windowsName"; var a = { name: "Cherry", fn() { setTimeout(()=>{ console.log(this.name); },0) } } a.fn() //Cherry

解析: 首先对象a调用fn函数,所以fn函数的this指向对象a,然后箭头捕获外层this,那么就不是setTimeout里的this,而是fn函数的this,所以最后拿到对象a里的name

定时器

对于延时函数内部的回调函数的this指向全局对象window

var name = "windowsName"; var a = { name: "Cherry", fn() { setTimeout(function (){ console.log(this.name); },0) } } a.fn() //windowsName

解析: 首先对象a调用fn函数,然后这里setTimeout里的回调函数是匿名函数,为普通的函数,那么匿名函数中的this指向的就是window

var name = "windowsName"; var b={ name: "setTimeoutName" } var a = { name: "Cherry", fn() { setTimeout((function (){ console.log(this.name); }).bind(b),0) } } a.fn() //setTimeoutName

解析:首先对象a调用fn函数,然后这里setTimeout里的回调函数是匿名函数,为普通的函数,那么匿名函数中的this指向的就是window,但使用bind改变匿名函数的this指向为对象b,所以最后对象b里的name

构造函数

构造函数中的this指向创建的实例对象,

注意:如果构造函数中返回一个对象,创建时不会有新的实例对象,而是这个返回的对象

function fn(){ this.age = 37; } var a = new fn(); console.log(a.age); // 37 a.age = 38; console.log(fn); // { this.age = 37; } console.log(a.age); // 38

解析:这里我们通过构造函数创建实例对象a,相当于开辟一个新地方将构造函数内容复制过来,就有了a对象,这时候this指向的就是对象a,我们修改对象a中内容不影响构造函数

点号判断

通过.判断this指向,遵循就近原则

var a = { age:10, b: { age:12, fn(){ console.log(this.age); } } } a.b.fn(); //12

解析:对象a调用对象b的fn函数,fn函数前面有两个.,那么最近的是对象b,所以fn函数的this指向的就是对象b,最后拿到的就是对象b的age

var a = { age:10, b: { age:12, fn(){ console.log(this.age); //undefined } } } var c = { age:20, } var d = { age:30, } a.b.fn.bind(c).bind(d)(); //20

解析:对象a调用对象b的fn函数然后使用bind改变this的指向,这时候fn前后前后都有.,不看前面的.,只用看后面的,然后最近的bind改变this指向为c,那么此时fn函数的this指向的就是对象c,拿到的就是对象c的age

练习

function outerFunc() { console.log(this) // { x: 1 } function func() { console.log(this) // Window } func() } outerFunc.bind({ x: 1 })()

obj = { func() { const arrowFunc = () => { console.log(this._name) } return arrowFunc }, _name: "obj", } obj.func()() //obj func = obj.func func()() //undefined obj.func.bind({ _name: "newObj" })()() //newObj obj.func.bind()()() //undefined obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })() //bindObjapply、call、bind

使用 apply、call、bind 函数可以改变this的指向,上面this的例子中使用到

区别

thisArg , [ argsArray] call(thisArg, arg1, arg2, ...)

apply和call函数区别在于this后面传入的参数,apply中传的是一个数组,而call中传入的是展开的参数

bind(thisArg[, arg1[, arg2[, ...]]])()

  • 然后bind函数创建的是一个新的函数,需要手动去调用
  • 这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用

如有错误,请大家指正!!感谢大家阅读!

参考资料

juejin.cn/post/6946021671656488991#comment

本文共计1502个文字,预计阅读时间需要7分钟。

JS中this指向问题你能完全理解吗?

您能理解JavaScript中`this`指向的问题吗?下面这篇文章将带大家聊聊让人头疼的`this`指向问题,希望对大家有所帮助!

`this`的指向

在JavaScript中,`this`是一个关键字,它指向函数或方法被调用时的上下文对象。在不同的场景下,`this`的指向可能会有所不同。

以下是我们常见的几种`this`指向情况:

1. 作为对象的方法调用:当`this`作为对象的方法被调用时,它指向该对象。 javascript const obj={ name: '张三', sayName: function() { console.log(this.name); } }; obj.sayName(); // 输出:张三

JS中this指向问题你能完全理解吗?

2. 作为普通函数调用:当`this`作为普通函数被调用时,它指向全局对象(在浏览器中是`window`,在Node.js中是`global`)。 javascript function sayName() { console.log(this.name); } sayName(); // 输出:undefined(在浏览器中)

3. 构造函数调用:当使用`new`关键字调用函数时,`this`指向新创建的对象。 javascript function Person(name) { this.name=name; } const person=new Person('李四'); console.log(person.name); // 输出:李四

4. 箭头函数:箭头函数不绑定自己的`this`,它会捕获其所在上下文的`this`值。 javascript const obj={ name: '王五', sayName: ()=> { console.log(this.name); } }; obj.sayName(); // 输出:王五

判断`this`的指向方法

1. 函数调用方式:根据函数的调用方式,可以初步判断`this`的指向。

2.使用`console.log(this)`:在函数内部直接使用`console.log(this)`可以查看当前`this`的指向。

3.使用`Function.prototype.call`或`Function.prototype.apply`:这两个方法可以改变函数的执行上下文,从而改变`this`的指向。

`this`的最终指向

`this`的最终指向取决于函数的调用方式。在函数被调用时,`this`会根据调用方式确定其指向的上下文对象。

你能搞懂JavaScript的this指向问题吗?下面本篇文章带大家聊聊这令人烦恼的this指向问题,希望对大家有所帮助!

this的指向

在我们看见的各种介绍如何判断this的指向方法中,"this的最终指向的是那个调用它的对象" 这句话被视作核心,但是面对多种多样的情况,我们容易搞混。针对针对多种情况结合我的理解,我提出了一句话 “箭头,定时和构造,特殊情况特殊看,普通调用看点号,后面有点不看前,然后就近原则判,最后剩下就是window”

箭头函数

箭头函数的本身没有this,所有不存在this改变,它捕获外层的this使用

var name = "windowsName"; var a = { name: "Cherry", fn() { setTimeout(()=>{ console.log(this.name); },0) } } a.fn() //Cherry

解析: 首先对象a调用fn函数,所以fn函数的this指向对象a,然后箭头捕获外层this,那么就不是setTimeout里的this,而是fn函数的this,所以最后拿到对象a里的name

定时器

对于延时函数内部的回调函数的this指向全局对象window

var name = "windowsName"; var a = { name: "Cherry", fn() { setTimeout(function (){ console.log(this.name); },0) } } a.fn() //windowsName

解析: 首先对象a调用fn函数,然后这里setTimeout里的回调函数是匿名函数,为普通的函数,那么匿名函数中的this指向的就是window

var name = "windowsName"; var b={ name: "setTimeoutName" } var a = { name: "Cherry", fn() { setTimeout((function (){ console.log(this.name); }).bind(b),0) } } a.fn() //setTimeoutName

解析:首先对象a调用fn函数,然后这里setTimeout里的回调函数是匿名函数,为普通的函数,那么匿名函数中的this指向的就是window,但使用bind改变匿名函数的this指向为对象b,所以最后对象b里的name

构造函数

构造函数中的this指向创建的实例对象,

注意:如果构造函数中返回一个对象,创建时不会有新的实例对象,而是这个返回的对象

function fn(){ this.age = 37; } var a = new fn(); console.log(a.age); // 37 a.age = 38; console.log(fn); // { this.age = 37; } console.log(a.age); // 38

解析:这里我们通过构造函数创建实例对象a,相当于开辟一个新地方将构造函数内容复制过来,就有了a对象,这时候this指向的就是对象a,我们修改对象a中内容不影响构造函数

点号判断

通过.判断this指向,遵循就近原则

var a = { age:10, b: { age:12, fn(){ console.log(this.age); } } } a.b.fn(); //12

解析:对象a调用对象b的fn函数,fn函数前面有两个.,那么最近的是对象b,所以fn函数的this指向的就是对象b,最后拿到的就是对象b的age

var a = { age:10, b: { age:12, fn(){ console.log(this.age); //undefined } } } var c = { age:20, } var d = { age:30, } a.b.fn.bind(c).bind(d)(); //20

解析:对象a调用对象b的fn函数然后使用bind改变this的指向,这时候fn前后前后都有.,不看前面的.,只用看后面的,然后最近的bind改变this指向为c,那么此时fn函数的this指向的就是对象c,拿到的就是对象c的age

练习

function outerFunc() { console.log(this) // { x: 1 } function func() { console.log(this) // Window } func() } outerFunc.bind({ x: 1 })()

obj = { func() { const arrowFunc = () => { console.log(this._name) } return arrowFunc }, _name: "obj", } obj.func()() //obj func = obj.func func()() //undefined obj.func.bind({ _name: "newObj" })()() //newObj obj.func.bind()()() //undefined obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })() //bindObjapply、call、bind

使用 apply、call、bind 函数可以改变this的指向,上面this的例子中使用到

区别

thisArg , [ argsArray] call(thisArg, arg1, arg2, ...)

apply和call函数区别在于this后面传入的参数,apply中传的是一个数组,而call中传入的是展开的参数

bind(thisArg[, arg1[, arg2[, ...]]])()

  • 然后bind函数创建的是一个新的函数,需要手动去调用
  • 这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用

如有错误,请大家指正!!感谢大家阅读!

参考资料

juejin.cn/post/6946021671656488991#comment