Day [2] — this:作用域 — JS之浸猪笼系列

如果你不知道这个系列为什麽叫这种激烈的名字可以看这篇:
Day [0] — JS之浸猪笼系列

如果你还没看过这篇 ,可能会有点难理解今天这篇,建议你先企看看!
Day [1] — this:存在於物件 — JS之浸猪笼系列

Day [2] — this:作用域

直接进入范例主题!!!σ ゚∀ ゚) ゚∀゚)σ

//来个范例吧!

var a = 100;

var obj = {
  a: 200,
  fn: function() {
	    var test = function() {
      console.log(this.a)
    }
    test()
  }
}

obj.fn() //100

//....恩?为什麽是100?(゚д゚≡゚д゚)
//作用域去哪里ㄌ?他本来还在的啊?

https://s3.us-west-2.amazonaws.com/secure.notion-static.com/fe7a6ddf-f115-431d-a6c4-d9b197aeb7ab/_2021-01-05_1.52.27.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20210106%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210106T055509Z&X-Amz-Expires=86400&X-Amz-Signature=6a8bae753d3ddf979da3a63207be6c61ab07b46567242dc0932846ede9ee73d2&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22_2021-01-05_1.52.27.png%22

先不要激动,我们来看看到底发生了什麽事情....

//来个范例吧!
//范例一解析

var a = 100; 
//我们宣告 a = 100,这是一个全域变数

var obj = {
		a: 200, // a 在物件内的值为 200

				fn: function() {

				    var test = function() {
				    console.log(this.a)}** 

		    test() } //记住我们在这里呼叫了test
}

obj.fn() //100

//解析一下
//让我们用倒叙法回推,
//obj.fn() 所以我们要去找 obj(物件)里的 fn 的值,
//往上看 fn,会发现 fn 是个函式,
//他会运算出 var test = function() {console.log(this.a)} 的值,
//记得我们在 fn 这个函式中 呼叫了 test();
//让 this 去找出了第一行的 var a = 100; 

//什麽意思?
//意思是 this 自动去指向了 window !(没想到吧)

//所以最後印出的值就是 obj.fn() //100


窝噗懂....为什麽会这样?

让我们印得比说得快!σ ゚∀ ゚) ゚∀゚)σ

//来个范例吧!
//范例二

function hello(){
  console.log(this)
}

hello()//猜猜这里会印出啥?
//是......window !σ ゚∀ ゚) ゚∀゚)σ

https://s3.us-west-2.amazonaws.com/secure.notion-static.com/41dd3046-ea9c-4ca8-88bf-ef71598bd1a6/_2021-01-05_2.21.48.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20210106%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20210106T055705Z&X-Amz-Expires=86400&X-Amz-Signature=bc1781d27279d9b2b09b89b66ab088e7db68086db00ef06a547caa1f5af84157&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22_2021-01-05_2.21.48.png%22

从这边开始我们就可以正式进入This的正题了!为啥在上面那个范例里,this会指向window呢?

day[1]的文章 中提到『 this 在函数运行的时候自动指向 instance(物件实体) 的属性。』

在上面那个范例中,我们并没有让 this 指向任何的物件,那 this 会指向哪呢?

你以为答案永远是 window 吗? 错!σ ゚∀ ゚) ゚∀゚)σ


实际上在this没有被指向 instance(物件实体)时,会指向的地方有这三种:

  1. 严格模式底下就都是undefined
  2. 非严格模式,浏览器底下是window
  3. 非严格模式,node.js 底下是global

一但脱离了物件,this 的值就没什麽意义,在没意义的情况底下就会有个预设值,而预设值也很好记,严格模式就是undefined,非严格模式底下就是全域物件。

(看懂这边的话可以在往上看一次范例一)


看了上面的解析和范例,聪明的你应该已经发现 this 的值跟作用域跟程序码的位置在哪里完全无关,只跟「你如何呼叫」有关。

//来个范例吧!
//范例三

const obj = {
  value: 1,
  hello: function() {
    console.log(this.value)
  }
}

obj.hello() 
// 这里会印出 1,我们怎麽呼叫的?

//我们最终的结果是要得到 obj.hello()
//obj我们已经知道他是物件,
//而其中 hello 是 function() {console.log(this.value)}

//在 obj这个物件中,this 会自动指向到 obj,
//当我们呼叫 obj.hello() 时等同於我们说 this 是 obj,
//为啥?因为他就是个代名词!

const hey = obj.hello
hey() // 这里会印出 undefined,我们怎麽呼叫的?

//为什麽换成 hey = obj.hello 就不是 1 了呢?
//答案也是:因为作用域。
//const hey = obj.hello 时,
//hey已经形成一个封闭的作用域(注一),
//所以 this 在 const(严格模式)底下就都是undefined。

//注一:
//const → 区块作用域(block scope),其作用范围是在它们被定义的区块里面。


引用及参考资讯

What's THIS in JavaScript ? [上]

浅谈 JavaScript 头号难题 this:绝对不完整,但保证好懂

this 的值到底是什么?一次说清楚


<<:  Day [1] — this:存在於物件 — JS之浸猪笼系列

>>:  [Github] Github 打破100MB限制 上传大型档案 ㄏㄏ

Day0 前言+碎念(可跳过

嗨~大家好!! 我是饿麟,你们也可以叫我小饿 今天是铁人赛开赛的第1天 身为一个小白,我正思考着也许...

Day 18 self-attention的实作准备(四) keras的compile和fit

前言 昨天讲到要如何建立model,今天来讲要如何训练以及预测 编译模型 建立完模型之後,必须呼叫c...

async/await 连体婴

前言 非同步概念的最後一小块拼图,要来学习怎麽使用 async/await async/await ...

我想用 AJAX,但是...

现在使用者对网页应用程序的要求越来越高,又要好看又要反应快。常见的做法是使用 AJAX 提升页面反应...

Day09 Platform Channel - BasicMessageChannel

如同前面介绍的,Flutter 定义了三种不同型别的Platform Channel 在platfo...