十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇文章给大家分享的是有关如何解决js中this指向问题,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
网站建设哪家好,找成都创新互联公司!专注于网页设计、网站建设、微信开发、成都微信小程序、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了宾川免费建站欢迎大家使用!

相信我,只要记住本文的7步口诀,就能彻底掌握 JS 中的this指向。
先念口诀:箭头函数、new、bind、apply 和 call、欧比届点(obj.)、直接调用、不在函数里。
按照口诀的顺序,只要满足前面某个场景,就可以确定this指向了。
接下来按照口诀顺序对它们进行详解,文中示例代码都运行在Chrome的Console控制台中。
文末有精心准备的练习题,用于检验学习成果,别忘了试试~
箭头函数排在第一个是因为它的this不会被改变,所以只要当前函数是箭头函数,那么就不用再看其他规则了。
箭头函数的this是在创建它时外层this的指向。这里的重点有两个:
1、创建箭头函数时,就已经确定了它的this指向。
2、箭头函数内的this指向外层的this。
所以要知道箭头函数的this就得先知道外层this的指向,需要继续在外层应用七步口诀。
当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象。
读者可能会有疑问,“如果使用new关键调用箭头函数,是不是箭头函数的this就会被修改呢?”。
我们在控制台试一下。
func = () => {}
new func() // throw error
从控制台中可以看出,箭头函数不能当做构造函数,所以不能与new一起执行。
bind 是指 Function.prototype.bind() 详细地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
易错点
function func() {
console.log(this)
}
func.bind(1).bind(2)() // 1func = () => {
// 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
console.log(this)
}
func.bind(1)() // Window,口诀 1 优先易错点
function func() {
console.log(this, this.__proto__ === func.prototype)
}
boundFunc = func.bind(1)
new boundFunc() // Object true,口诀 2 优先apply()和 call()的第一个参数都是this,区别在于通过apply调用时实参是放到数组中的,而通过call调用时实参是逗号分隔的。
易错点
func = () => {
// 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
console.log(this)
}
func.apply(1) // Window,口诀 1 优先易错点
function func() {
console.log(this)
}
boundFunc = func.bind(1)
boundFunc.apply(2) // 1,口诀 3 优先function func() {
console.log(this.x)
}
obj = { x: 1 }
obj.func = func
obj.func() // 1这里就不用代码例证箭头函数和 bind 函数的优先级更高了,有兴趣可自行尝试吧。
在函数不满足前面的场景,被直接调用时,this将指向全局对象。在浏览器环境中全局对象是Window,在Node.js环境中是Global。
先来个简单的例子。
function func() {
console.log(this)
}
func() // Window来一个复杂的例子,外层的outerFunc就起个迷惑目的。
function outerFunc() {
console.log(this) // { x: 1 }
function func() {
console.log(this) // Window
}
func()
}
outerFunc.bind({ x: 1 })()不在函数中的场景,可分为浏览器的标签里,或Node.js的模块文件里。
1、在标签里,this指向Window。
2、在Node.js的模块文件里,this指向Module的默认导出对象,也就是module.exports。
严格模式是在ES5提出的。在ES5规范之前,也就是非严格模式下,this不能是undefined或null。所以**在非严格模式下,通过上面七步口诀,如果得出this指向是undefined或null,那么this会指向全局对象。**在浏览器环境中全局对象是Window,在Node.js环境中是Global。
例如下面的代码,在非严格模式下,this都指向全局对象。
function a() {
console.log("function a:", this)
;(() => {
console.log("arrow function: ", this)
})()
}
a()
a.bind(null)()
a.bind(undefined)()
a.bind().bind(2)()
a.apply()非严格模式下执行结果为:

在严格模式下,执行同样的代码进行对比。记住要一次性将所有代码复制粘贴到控制台中,才能运行在严格模式下(因为第一行 "use strict" 才会对后面的代码生效)。
"use strict"
function a() {
console.log("function a:", this)
;(() => {
console.log("arrow function: ", this)
})()
}
a()
a.bind(null)()
a.bind(undefined)()
a.bind().bind(2)()
a.apply()严格模式下执行结果为:

七步口诀在严格模式下和非严格模式下都是完备的,只是在非严格模式下null或undefined会被转换为全局对象。所以我没有将这点列入口诀中。
先背诵口诀再做题,“箭头函数、new、bind、apply和call、欧比届点(obj.)、直接调用、不在函数里”。
1. 下面代码执行后,func.count 值为多少?
function func(num) {
this.count++
}
func.count = 0
func(1)答案
func.count值为 0。
按照口诀,func()调用时属于第 6 类「直接调用」。在非严格模式下,this指向全局对象。this跟func 一点关系都没有,所以 func.count保持不变so easy。
obj = {
func() {
const arrowFunc = () => {
console.log(this._name)
}
return arrowFunc
},
_name: "obj",
}
obj.func()()
func = obj.func
func()()
obj.func.bind({ _name: "newObj" })()()
obj.func.bind()()()
obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })()答案
// obj // undefined // newObj // undefined // bindObj
是不是很简单,你学废了吗?
以上就是如何解决js中this指向问题,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。