js中的this指向问题,js中this的指向有几种情况
JS中this指向问题
相信我,只要记住这篇文章的7步公式,你就能在JS中彻底把握这个方向。
先看公式:箭头函数,新建,绑定,应用和调用,obj。直接调用,不在函数里。
根据公式的顺序,只要满足前面的场景,就可以确定这指向。
接下来,按照公式的顺序对它们进行详细说明。本文中的示例代码都运行在Chrome的控制台控制台中。
文末有精心准备的练习,检验学习成果。别忘了试试它们~
1. 箭头函数
箭头函数之所以排在第一位,是因为它的this不会被改变,所以只要当前函数是箭头函数,那么就不需要看其他的规则。
箭头的这一点是外层这一点在它被创建的时候。这里有两个关键点:
1.当箭头函数被创建时,它的这个点就已经被确定了。
2.箭头函数中的这个指向外层中的这个。
所以要知道arrow函数的这个,首先要知道这个在外层的方向,需要继续应用外层的七步公式。
2. new
当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象。
读者可能会想,“如果用新键调用箭头函数,箭头函数的this会被修改吗?”。
让我们在控制台上试试。
func=()={}
new func() //抛出错误
从控制台可以看到,arrow函数不能作为构造函数使用,所以不能用new执行。
3. bind
多次 bind 时只认第一次 bind 的值
易错点
函数func() {
console.log(this)
}
func.bind(1)。bind(2)() //1
箭头函数中 this 不会被修改
func=()={
//这里这个点取决于外层这个,参考公式7“不在函数中”
console.log(this)
}
Func.bind(1)() //窗口,公式1优先
bind 与 new
易错点
函数func() {
console.log(这个,这个。__proto__===func.prototype)
}
boundFunc=func.bind(1)
New boundFunc() //Object true,公式2优先
4. apply 和 call
apply()和call()的第一个参数是这个,不同的是apply调用时实参放入数组,call调用时用逗号隔开。
箭头函数中 this 不会被修改
易错点
func=()={
//这里这个点取决于外层这个,参考公式7“不在函数中”
console.log(this)
}
Func.apply(1) //Window,公式1优先
bind 函数中 this 不会被修改
易错点
函数func() {
console.log(this)
}
boundFunc=func.bind(1)
BoundFunc.apply(2) //1,公式3优先
5. 欧比届点(obj.)
func func(){
console.log(this.x)
}
obj={ x: 1 }
obj.func=函数
Obj.func() //1这里不需要编码来说明箭头函数和绑定函数的优先级更高。有兴趣的话可以自己试试。
6. 直接调用
当函数不满足前面的场景而被直接调用时,这将指向全局对象。在浏览器环境中,全局对象是Window,在Node.js环境中,它是全局的。
让我们从一个简单的例子开始。
函数func() {
console.log(this)
}
Func() //Window举个复杂的例子,外层的outerFunc起到了混淆的作用。
函数outerFunc() {
console.log(this) //{ x: 1 }
函数func() {
console.log(this) //窗口
}
函数()
}
Outfunc.bind ({x: 1}) ():
7. 不在函数里
不在函数中的场景可以分为浏览器的脚本/标签或者Node.js的模块文件
1.在脚本/标签中,这指向窗口。
2.在Node.js的模块文件中,它指向模块的默认导出对象,即module.exports
非严格模式
在ES5中提出了严格模式。在ES5规范之前,即在非严格模式下,这不能是未定义的或空的。所以* *在非严格模式下,通过上面的七步公式,如果断定this指向undefined或者null,那么this就会指向全局对象。* *全局对象在浏览器环境中是Window,在Node.js环境中是Global。
例如,在下面的代码中,在非严格模式下,这都指向全局对象。
函数a() {
console.log(函数a:,this)
;(()={
console.log(箭头函数: ,this)
})()
}
答()
a.bind(null)()
a.bind(未定义)()
a.bind()。绑定(2)()
A.a.apply()在非严格模式下的执行结果是:
在严格模式下,执行相同的代码进行比较。记住将所有代码一次复制并粘贴到控制台中,以在严格模式下运行(因为第一行 use strict 将对后面的代码生效)。
使用严格
函数a() {
console.log(函数a:,this)
;(()={
console.log(箭头函数: ,this)
})()
}
答()
a.bind(null)()
a.bind(未定义)()
a.bind()。绑定(2)()
A.apply()在严格模式下,执行结果是:
七步公式在严格模式和非严格模式下都是完整的,但在非严格模式下null或undefined会被转换成全局对象。所以我没有把这个包括在我的公式里。
做题复习
做题前背诵公式,“箭头函数,新建,绑定,应用和调用,奥比万点(obj。),直接调用,不在函数里”。
1. 下面代码执行后,func.count 值为多少?
func func(num){
这个.计数
}
func.count=0
功能(1)答案
func.count值为0。
根据公式,调用func()时,属于类别6“直接调用”。在非严格模式下,这指向全局对象。和这个func无关,所以func.count保持不变这么容易。
2. 以下箭头函数中 this 指向谁呢?
obj={
func() {
const arrowFunc=()={
console.log(这个。_name)
}
返回箭头Func
},
_name: obj ,
}
obj.func()()
func=obj.func
func()()
obj.func.bind({ _name: newObj })()()
obj.func.bind()()()
obj . func . bind({ _ name: bind obj })。申请({ _name: applyObj })()答案
//obj
//未定义
//newObj
//未定义
bindobj是不是很简单?你学会浪费了吗?
推荐:js视频教程以上是JS中这个指点问题(附代码)的详细内容。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。