this指向who

我们很常会在function中看到使用this这个关键字。但它是甚麽,要怎麽用?听说它的判断方法很麻烦? 不急,我们先来看看生活中的this
https://github.com/Hsu-Linda/front-end-baby-bird/blob/main/this/%E6%88%91%E5%AE%B6%E4%BD%8F%E5%9C%A8%E5%8F%B0%E5%8C%97%E5%B8%82.gif?raw=true

生活中的this可以帮我们省去一直讲重复的词,让句子比较简洁。
程序里的this,一样帮我们省去一些词,只不过这个词,指向执行「程序码」的「物件」。

生活中的「这个」「那个」常常搞到最後,有人都不知道在说哪个。
JS里也不例外,一样有「对牛谈this」的情形。所以为了想正确设定执行程序码的物件,我们需要来好好跟this讨教讨教


this 、 function 和 object

大部分情况下,this的值取决於呼叫function的方法。(此方法不是指,function或指隶属於object底下的function:method,可以想成:语法的意思,不要误会喔)
不同的呼叫方法,会让this指向不同的呼叫function的物件。

ok,重点笔记。我们比刚刚又知道更多了一点:从指向「执行码」的物件,变成指向「呼叫function」的物件。所以大概率this、function跟object是分不了家的~
→ this 指向 「呼叫函式(function)」的「物件(object)」


呼叫function的方法 与 this指向的「呼叫function的物件」

既然我们知道this会指向「呼叫function的物件」。那很明显,当呼叫一个function时,我们要去绑定this和物件。我们的小任务就是要去观察:在甚麽情况下,跟谁绑?(when,who)

四种系结

  • 预设系结
  • 隐含系结
  • 明确系结
  • new系结

预设系结 (Default Binding)

  • 甚麽时候使用when :
    • 方法名.()
    • 明确系结,但没定义this → i.e. 方法名.call(null,参数1,参数2,...,参数n) 、方法名.call()
      (後面再示范)
  • this跟谁绑who :
    • JS文档最前面有 'use strict'; :
      在JS严格的监控下,没人敢跟this绑,所以是undefined

    • 没有写'use strict' 非严格模式:this 跟全域物件绑
      还记得我们上一篇说全域物件是谁吗?

      .

      .

      .

      没错,在浏览器是window物件,在node是global物件,所以这里this是跟window物件绑

var str = 'Here is Global';
function logStr (){
	var str = 'Here is Local';
	console.log(this.str)
}

logStr();

猜猜是log出global还是local?反正我第一次是猜错的

.

.

.

公布答案:Here is Global

解析:
跟我一样错的人往上看,when的第一个,方法名.(),这里用的就是他。
既然如此,this就会跟全域物件window绑定。(可以直接在主控台打this看看,真的会看到window喔,没有跟你唬,你说虎不虎)
接着this.str,意味着window.str,在全域找str这个变数,再之後就log出global来啦~ok下一关

先打个岔,刚刚稚鸟一下讲函式,一下讲方法的,他们一样吗?感受到困惑惹?~~厘清一下罗

function函式 method方法 系摀差?(是有差?)

  • function叫函式
  • 建一个object(物件),物件里面设(属性名)属性
    (想叫啥都可以,如果是在主控台印字串,可以叫他logString属性)
  • function(函式)令给(属性名)属性
    此时属性值为function(函式)的属性,称为该objectmethod(方法)

程序码长这样

//object物件
var obj={};
//function函式 我们用宣告法
function  fk(){
	console.log('hi');
};
//等号左边我们令一个属性
//等号右边我们把function函式,令给属性 
//此时该属性称为物件object的方法method
//没要执行,就不要小括号();想要执行,小括号就加好加满
obj.fkProperty = fk;
  • 属性存放的指是function的记忆体地址,所以function不会永远属於哪一个物件
    他可以把记忆体地址传给别人,共享这个function

打岔结束

隐含系结(Implicit Binding)

  • 甚麽时候使用when :当把他当作某物件的方法method调用(呼叫)时
  • this跟谁绑who :调用他的某物件
var str = 'Here is Global',
//obj1,obj2各自放不同的str
//obj1,obj2都把logStr function放入物件的log属性中 (放进去才有办法用隐含系结调用压)
		obj1={str:'Here is Obj1' ,log:logStr}, 
		obj2={str:'Here is Obj2' ,log:logStr , friend:obj1};
function logStr (){
	var str = 'Here is Local';
	console.log(this.str);
};

obj1.log();  //Here is Obj1
obj2.log();  //Here is Obj2
this.log();  //等价於 window.log()  全域没有log这个function 
						 //Uncaught TypeError: this.log is not a function
obj2.friend.log();  //Here is Obj1

解析:

  • obj1.log();
    1. 在全域找到obj1物件,在obj1物件找到log method=(找到log属性)
    2. 用()执行log method的值:logStr function 同时 this指向obj1
    3. 产生function内变数 var str = 'Here is Local';
    4. 执行 console.log(this.str) 等价於执行 console.log(obj1.str)
  • obj2.friend.log();
    1. 在全域找到obj2物件,在obj2物件找到friend属性,friend属性的值是obj1物件
    2. 因为区域内可以存取区域外的值(i.e. 全域的值),所以obj2可以存取在全域的obj1
    3. 在obj1物件找到log method
    4. 接续obj1.log()的解析

参考资料

JavaScript - This (1) - iT 邦帮忙::一起帮忙解决难题,拯救 IT 人的一天


日常干话:
今天就这样愉快的结束了,明天还有三个方法呦


<<:  [RouterOS] NAT port 映射问题

>>:  [第五天]从0开始的UnityAR手机游戏开发-如何在Vuforia创建可辨识图片

【Day22】导航元件 - Tabs

元件介绍 Tabs 是一个选项卡切换元件,能够在同一层级的内容组别当中导航、切换。此元件由两个部分构...

Day23 | Livewire 实作 购物网站(二): 建立商品细节页面

有了商品列表,那应该要能点进去看商品的细节吧。所以今天就是来做点进去後的商品细节页! 今日目标:商品...

沟通技巧中的利害关系人管理

产品经理平常需要沟通的对象很多,而这些对象对专案的影响程度大小可能不尽相同,为了有效的擅用产品经理自...

[Day28] 前端部署网页的方式 (Vercel, AWS S3 & Netlify)

今天要和大家介绍的是前端部署网页的方法,分别是以下三个: Vercel AWS S3 Netlif...

DAY 3- Enigma

纳粹德国的超强机器,唯有机器才能破解机器。 今天来介绍二战时期被纳粹大规模使用的加密机器 - Eni...