日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

lambda 表达式中的 this 与普通情况下的 this 指向

發(fā)布時(shí)間:2024/4/13 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lambda 表达式中的 this 与普通情况下的 this 指向 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

lambda 表達(dá)式中的 this 與普通情況下的 this 指向

  • Java
  • JavaScript
    • this 綁定
    • 總結(jié)與提醒

??很多編程語(yǔ)言都支持 lambda 表達(dá)式,不過(guò)對(duì)于不同編程語(yǔ)言,其 lambda 表達(dá)式中 this 指向差異很大,有些甚至相反。下面舉例如下。

Java

??對(duì)于 Java 語(yǔ)言,很普通情況下的 this 很好理解,這里不在詳述。值得一提的是 Java 中的內(nèi)部類(lèi)。

??Java 的內(nèi)部類(lèi)有:成員內(nèi)部類(lèi)、局部?jī)?nèi)部類(lèi)、匿名內(nèi)部類(lèi)、靜態(tài)內(nèi)部類(lèi)。這里只講述匿名內(nèi)部類(lèi),因?yàn)槠渌膬?nèi)部類(lèi)中的 this 指向都不易混淆,所以從略。

  • 對(duì)于 Java 中的匿名內(nèi)部類(lèi),編譯器會(huì)自動(dòng)生成它的類(lèi)名,而自動(dòng)生成的類(lèi)名為外部類(lèi)類(lèi)名$數(shù)字。而匿名內(nèi)部類(lèi)中的 this,將指向的是這個(gè)內(nèi)部類(lèi)對(duì)象。

  • 對(duì)于 Java 中的 lambda 表達(dá)式中的 this,指向的是 lambda 表達(dá)式所在類(lèi)的對(duì)象。也就是說(shuō),對(duì)一個(gè)類(lèi)來(lái)說(shuō),lambda 表達(dá)式中的 this,與普通表達(dá)式中的 this,沒(méi)有任何區(qū)別。

JavaScript

??關(guān)于 JavaSript 中的 this 使用,一般分為普通表達(dá)式中的 this、匿名函數(shù)中的 this 和箭頭函數(shù)中的 this。

??注意:JavaScript 中的匿名函數(shù)與箭頭函數(shù)不是同一個(gè)東西。JavaScript 中的匿名函數(shù)又叫 lambda 函數(shù),但從形式上,JavaScript 中的箭頭函數(shù)才像 Java 中的 lambda 表達(dá)式。例如。

/*** 常規(guī)函數(shù)*/ function showName() {console.log(this.name); }/*** 匿名函數(shù)(lambda 函數(shù))*/ let showSex = function() {console.log(this.sex); }/*** 箭頭函數(shù)*/ let showAge = () => console.log(this.age);
  • 對(duì)于普通表達(dá)式中的 this 所處的位置,可以分為以下情況:

    • 含 this 的表達(dá)式?jīng)]有位于任何函數(shù)中。在這種情況,此 this 指向?qū)ο?window(非嚴(yán)格模式下)或?yàn)?undefined(嚴(yán)格模式下)。

    • 含 this 的表達(dá)式位于一個(gè)函數(shù)中。在這種情況,此 this 指向調(diào)用該函數(shù)的對(duì)象。

      特別地,當(dāng) this 直接位于一個(gè)構(gòu)造函數(shù)中(即此 this 外最近一層的函數(shù)為構(gòu)造函數(shù)),此 this 指向該構(gòu)造函數(shù)所創(chuàng)建的對(duì)象(即,視調(diào)用構(gòu)造函數(shù)的對(duì)象為該構(gòu)造函數(shù)所創(chuàng)建的對(duì)象)。

      注意:不能武斷地通過(guò)判斷此含 this 的表達(dá)式所處的位置來(lái)斷定 this 的指向。即,不能認(rèn)為此含 this 的表達(dá)式位于某個(gè)對(duì)象內(nèi),就認(rèn)為該 this 指向那個(gè)對(duì)象。判斷 this 的指向還需要通過(guò)判斷含 this 的函數(shù)在哪里被調(diào)用。

    例如(假設(shè)下面的代碼均位于非嚴(yán)格模式下):

    window.color = 'red'; let obj = {color: 'blue' };function sayColor() {console.log(this.color); }/*** 沒(méi)有使用對(duì)象來(lái)調(diào)用 sayColor(),this 默認(rèn)指向 window。*/ sayColor(); // redobj.sayColor = sayColor; /*** 使用對(duì)象來(lái)調(diào)用 sayColor(),this 指向?qū)ο?obj。*/ obj.sayColor(); // blue
  • 對(duì)于匿名函數(shù)中的 this,它與普通表達(dá)式中的 this 的指向規(guī)則是一樣的,因此此處不再詳述。

  • 對(duì)于箭頭函數(shù)中的 this,其指向直接包含此箭頭函數(shù)定義的函數(shù)所屬的對(duì)象。

    【注意】

    • 是包含箭頭函數(shù)的函數(shù),不是包含 this 的箭頭函數(shù)。

    • “直接”指的是包含箭頭函數(shù)的函數(shù)必須是箭頭函數(shù)外的最近一層的函數(shù)。

    • 當(dāng)箭頭函數(shù)沒(méi)有位于某一個(gè)函數(shù)中時(shí),此處的“函數(shù)”理解為“上下文”。

    不過(guò),由于 JavaScript 中的函數(shù)的歸屬可以改變,因此此處也不能直接通過(guò)判斷此含 this 的表達(dá)式所處的位置來(lái)斷定 this 的指向,還是要看含該箭頭函數(shù)的函數(shù)被調(diào)用的位置。

    例如,對(duì)于普通情況下:

    window.color = 'red'; let obj = { color: 'blue' };/*** 原箭頭函數(shù)沒(méi)有位于某一個(gè)函數(shù)中,而位于全局*/ let sayColorGlobalArrowFun = () => console.log(this.color); /*** 原箭頭函數(shù)沒(méi)有位于某一個(gè)函數(shù)中,那就更沒(méi)有該函數(shù)顯式的所屬對(duì)象了,* 因此默認(rèn)所屬對(duì)象為 window。于是 this 恒指向 window*/ sayColorGlobalArrowFun(); // redobj.sayColorGlobalArrowFun = sayColorGlobalArrowFun; /*** 原箭頭函數(shù)沒(méi)有位于某一個(gè)函數(shù)中,那就更沒(méi)有該函數(shù)顯式的所屬對(duì)象了,* 因此默認(rèn)所屬對(duì)象為 window。于是 this 恒指向 window*/ obj.sayColorGlobalArrowFun(); // redfunction sayColorNorFun() { // NorFun:Normal Function/*** 原箭頭函數(shù)代碼位于函數(shù) sayColorNorFun 中*/let sayColorLocalArrowFun = () => console.log(this.color); sayColorLocalArrowFun(); } /*** 原箭頭函數(shù)代碼位于函數(shù) sayColorNorFun 中,* 而此處函數(shù) sayColorNorFun 屬于對(duì)象 window。* 于是 this 指向 window*/ sayColorNorFun(); // redobj.sayColorNorFun = sayColorNorFun; /*** 原箭頭函數(shù)代碼位于函數(shù) sayColorNorFun 中,* 而此處函數(shù) sayColorNorFun 屬于對(duì)象 obj。* 于是 this 指向 obj*/ obj.sayColorNorFun(); // blue

    對(duì)于將包含箭頭函數(shù)的函數(shù)作為構(gòu)造函數(shù)時(shí):

    function King() {/*** this 直接位于一個(gè)普通函數(shù)中。在本文后面的調(diào)用中,其指向 King 對(duì)象*/this.royaltyName = 'Henry';/*** this 直接位于一個(gè)箭頭函數(shù)中。在本文后面的調(diào)用中,其指向 King 對(duì)象* * 注意:不能看代碼看到這里就斷定此處的 this 恒指向 window,* 要看含函數(shù) King() 被調(diào)用處附近的代碼。* 但通常情況下,可以猜測(cè) this 恒指向 window*/setTimeout(() => console.log(this.royaltyName), 1000); }function Queen() {/*** this 直接位于一個(gè)普通函數(shù)中。在本文后面的調(diào)用中,其指向 Queen 對(duì)象*/this.royaltyName = 'Elizabeth';/*** this 直接位于一個(gè)匿名函數(shù)中*/setTimeout(function() { console.log(this.royaltyName); }, 1000); }/*** 此處將函數(shù) King() 作為構(gòu)造函數(shù),因此 this 指向此處“new”創(chuàng)建的 King 對(duì)象,* 同時(shí)還調(diào)用了函數(shù) King() */ new King(); // Henry/*** 此處將函數(shù) Queen() 作為構(gòu)造函數(shù),但由于 this 位于一個(gè)匿名函數(shù)中,* 而此匿名函數(shù)將由函數(shù) setTimeout 來(lái)調(diào)用,* 而函數(shù) setTimeout 將不會(huì)使用顯式的對(duì)象來(lái)調(diào)用此匿名函數(shù),因此視調(diào)用方為 window* * 注意:此處并不是因?yàn)椤皀ew Queen()”位于全局,所以認(rèn)為調(diào)用方為 window,* 而是因?yàn)橹苯影思^函數(shù)代碼的是一個(gè)匿名函數(shù),而此匿名函數(shù)的調(diào)用方為 window*/ new Queen(); // undefined

this 綁定

??既然 JavaScript 中普通函數(shù)與匿名函數(shù)中的 this 如此危險(xiǎn),有什么辦法可以回避這個(gè)風(fēng)險(xiǎn)呢?一種方法是改用箭頭函數(shù),如果箭頭函數(shù)所處的上下文是確定的對(duì)象,那么它的 this 指向就不會(huì)改變。

??但有些時(shí)候,需要這個(gè) this 不事先確定,這有點(diǎn)像面向?qū)ο笳Z(yǔ)言中基類(lèi)方法的 this 一樣。在 JavaScript 中,有時(shí)為了減少代碼冗余,會(huì)將一些共同代碼置入一個(gè)模塊中,供其它模塊使用,這個(gè)時(shí)候,希望 this 指向調(diào)用模塊的上下文。不過(guò)考慮函數(shù)傳遞調(diào)用(一個(gè)函數(shù)調(diào)用另一個(gè)函數(shù),而后者再調(diào)用另一個(gè)函數(shù)),這個(gè)時(shí)候判斷 this 的指向會(huì)變得很麻煩。為此,JavaScript 提供了函數(shù) bind 來(lái)終結(jié)這個(gè)判斷難題。函數(shù) bind 可以間接強(qiáng)制規(guī)定一個(gè)函數(shù)中恒定的 this 指向。

??在 JavaScript 中,每個(gè)函數(shù)都是一個(gè)對(duì)象,每個(gè)函數(shù)對(duì)象都有一個(gè)函數(shù) bind,它接收一個(gè)對(duì)象參數(shù),然后返回一個(gè)函數(shù)。返回的這個(gè)函數(shù)與自己幾乎一樣,區(qū)別是,這個(gè)函數(shù)的 this 被強(qiáng)制綁定為傳入的這個(gè)對(duì)象參數(shù)。示例如下:

window.color = 'red';var obj = {color: 'blue' };function sayColor0() {console.log(this.color); }let sayColor = sayColor0().bind(obj);sayColor0(); // red sayColor(); // blue

總結(jié)與提醒

  • 當(dāng)兩個(gè) this 分別位于一個(gè)普通函數(shù)和一個(gè)箭頭函數(shù)中時(shí),它們的區(qū)別是,前者的 this 指向該普通函數(shù)(在被調(diào)用時(shí))所屬的對(duì)象(調(diào)用該普通函數(shù)的對(duì)象),而后者的 this 指向包含箭頭函數(shù)定義的上下文(在被調(diào)用時(shí))所屬的對(duì)象。

  • 如果把箭頭函數(shù)放置在一個(gè)函數(shù)中,則此箭頭函數(shù)中的 this 與普通函數(shù)的 this 的效果一樣的。因此,一般來(lái)說(shuō),不要把含 this 的箭頭函數(shù)放置在一個(gè)函數(shù)中,而應(yīng)該直接暴露在最外層的上下文中。這樣,此箭頭函數(shù)就永遠(yuǎn)指向當(dāng)時(shí)的上下文,而不管之后又將此箭頭函數(shù)傳遞給了誰(shuí)。

  • 之所以 this 在普通函數(shù)與箭頭函數(shù)中的行為有所不同,是因?yàn)?JavaScript 中的普通函數(shù)、匿名函數(shù)(lambda 函數(shù))都屬于函數(shù),但箭頭函數(shù)不屬于函數(shù),它只是一種特殊的表達(dá)式。而在 JavaScript 中,一個(gè)函數(shù)在被調(diào)用時(shí),會(huì)為其創(chuàng)建 this 與 arguments,因?yàn)榧^函數(shù)不屬于函數(shù),所以它自己沒(méi)有 this,它的 this 只能來(lái)源于外部的 this——也就是包含箭頭函數(shù)定義的上下文。

總結(jié)

以上是生活随笔為你收集整理的lambda 表达式中的 this 与普通情况下的 this 指向的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。