this指向 到底 怎么指向的?

看到最多的教程就是说 谁调用 指向谁。终于在这几天 弄明白其中的道理了。

先看一道面试题:

var name = 222
			var a = {
				name : 111,
				say : function(){
					console.log(this.name)
				}
			}
			var funb = a.say
			funb() 

			
			a.say() 
			
			var b = {
				name : 333,
				say : function(fun){
					console.log(this)
					fun()
				}
			}
			b.say(a.say)
			b.say = a.say
			b.say() 

问:打印结果?(答案 222 111 222 333)

正常分析

谁调用 this指向谁,很明显 funb() 中调用 this 指向window,所以打印222。a.say() 是 a 对象 调用 所以this指向 a 打印 111。这两个 都好说,到第三个 b.say(a.say) 这个看起来 有点难分析,b.say() 参数 是一个 方法,直接将a.say复制过去运行,那this指向哪?谁调用 这个地方 将 代码运行的 是window。

.call()分析

call 方法 (https://www.runoob.com/w3cnote/js-call-apply-bind.html)

funa(”) => funa.call(window,”) 在 函数 funa 中打印 this 。 this 指向 第一个参数 window。

同理 a.say(”) => a.say.call(a,”) this 指向 a。

这样 就突然理解 这个 this到底是 怎么指向的了。

看第三个 b.say(a.say) => b.say.call(b, say : function(){ console.log(this.name) } ) =>

b.say.call(b, say.call(window) ) 这个方法 是window对象执行 的 所以 this指向 window。

最后一个 b.say = a.say b.say() 这个就简单了 直接将代码复制给 b.say 运行时 b.say.call(b) 所以打印 333。

通过 引用 call 方法 ,理解 this变得更加简单了 。

现在 我们引入 箭头函数。

箭头函数:

箭头函数 不能为构造函数。箭头函数 this 指向自己代码块外的 代码区域。

var zz = {
				sex : "女",
				zzz : {
					sex : "男",
					a : () => {
						console.log("箭头函数",this) 
						console.log(this.sex)
					},
					
					b : function(){
						console.log("普通函数",this) 
						console.log(this.sex)
					},
					
					zzzz : {
						cc : function(){
								var ff = () => {
									console.log("这个是函数",this)
								}
							ff()
						}
					}
				},
			}
			zz.zzz.a()
			zz.zzz.b()
			zz.zzz.zzzz.cc()
			
			function myfun(){
				var name = "hello"
				function myfun1(){
					var name = "hello 1"
					console.log(this)
					let fn = () => {
						console.log(this) // window
					}
					fn()
				}
				myfun1()
			}
			myfun()

这种仔细分析 谁调用的 this 指向 类内的 函数 运行 ,箭头函数 this 指向 window。直接 运行的函数 this 都是 window调用的。对象 内 函数 内的 箭头函数 this 指向 当前 函数内的代码块。 window下直接调用的函数 内的 箭头函数 this 指向 window。

这是一个 继承作用域的概念。

因为 直接在window声明 调用的 函数 作用域继承于 window。在对象里调用 继承 对象作用域。

作者 译文

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注