JavaScript 中目前比較少見的表達式

??空值合并運算符es2020

??是一個邏輯操作符虎谢,當(dāng)左側(cè)的操作數(shù)為 null或者 undefined 時酬诀,返回其右側(cè)操作數(shù),否則返回左側(cè)操作數(shù)瞒御。

與邏輯或操作符||不同,邏輯或操作符會在左側(cè)操作數(shù)為假值時返回右側(cè)操作數(shù)肴裙。也就是說,如果使用 || 來為某些變量設(shè)置默認(rèn)值蜻懦,可能會遇到意料之外的行為。
比如為假值(例如宛乃,''0)時带欢。見下面的例子:

const foo = null ?? 'default string'
console.log(foo) // "default string"

const baz = 0 ?? 42
console.log(baz) // 0

const bar = false ?? true
console.log(bar) // false

注意??不能與 &&|| 操作符共用

null || undefined ?? "foo" // 拋出 SyntaxError
true || undefined ?? "foo" // 拋出 SyntaxError

但是乔煞,如果使用括號來顯式表明運算優(yōu)先級,是沒有問題的:

(null || undefined ) ?? "foo" // 返回 "foo"

?.可選鏈操作符es2020

可選鏈操作符?.允許讀取位于連接對象鏈深處的屬性的值渡贾,而不必明確驗證鏈中的每個引用是否有效。
?. 操作符的功能類似于 . 鏈?zhǔn)讲僮鞣塾遥煌幵谟冢谝脼榭罩狄词?null要么是 undefined的情況下不會引起錯誤擂仍,該表達式短路返回值是 undefined。與函數(shù)調(diào)用一起使用時逢渔,如果給定的函數(shù)不存在,則返回 undefined

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
}

const dogName = adventurer.dog?.name
console.log(dogName) // undefined

console.log(adventurer.someNonExistentMethod?.()) // undefined

console.log(adventurer.list?.forEach(() => {})) // undefined

對比一下代碼

const obj = {}
let nestedProp = obj.first?.second

這等價于以下表達式诲泌,但實際上沒有創(chuàng)建臨時變量:

const obj = {}
let temp = obj.first
let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second)

可選鏈與函數(shù)調(diào)用
當(dāng)嘗試調(diào)用一個可能不存在的方法時也可以使用可選鏈。

  • 函數(shù)調(diào)用時如果被調(diào)用的方法不存在铣鹏,使用可選鏈可以使表達式自動返回undefined而不是拋出一個TypeError
const someInterface = {}
let result = someInterface.customMethod?.()

可選鏈和表達式
當(dāng)使用方括號與屬性名的形式來訪問屬性時诚卸,你也可以使用可選鏈操作符:

let list = null
console.log(list?.[1]) // undefined

注意

  • 如果存在一個屬性名且不是函數(shù), 使用 ?. 仍然會產(chǎn)生一個TypeError異常
const someInterface = {
   customMethod: 'Not Method'
}

let result = someInterface.customMethod?.();
// Uncaught TypeError: someInterface.customMethod is not a function
  • 如果 someInterface 自身是 null 或者 undefined, 仍然會產(chǎn)生一個TypeError異常合溺,如果你希望允許 someInterface 也為 null 或者 undefined,那么你需要像這樣寫:
let someInterface = null
someInterface?.customMethod?.() // undefined

逗號運算符間接函數(shù)調(diào)用

先介紹一下逗號運算符
逗號運算符

對它的每個操作數(shù)求值(從左到右)辫愉,并返回最后一個操作數(shù)的值将硝。

let x = 1
x = (x++, x)
console.log(x) // 2

x = (2, 3)
console.log(x) // 3

(0, alert)('ByePast')逗號運算符衍生出來的間接函數(shù)調(diào)用

使用間接函數(shù)調(diào)用可以把該作用域內(nèi)倍的this指向全局對象中的this

在調(diào)用函數(shù)的上下文中,對操作數(shù)的評估只會得到一個值依疼,而不是引用痰腮,這會導(dǎo)致this被調(diào)用函數(shù)內(nèi)部的值指向全局對象(或者它將undefined處于新的 ECMAScript 5 嚴(yán)格模式)例如:

var foo = 'global.foo'

var obj = {
  foo: 'obj.foo',
  method: function () {
    return this.foo
  }
};

obj.method() // 'obj.foo'
(1, obj.method)() // 'global.foo'

如您所見膀值,第一次調(diào)用,即直接調(diào)用误辑,this內(nèi)部的值method將正確引用obj(返回'obj.foo'),第二次調(diào)用巾钉,逗號運算符所做的評估將使this值指向全局對象(產(chǎn)生'global.foo')。

這種模式很流行砰苍,要間接調(diào)用eval,這在 ES5 嚴(yán)格模式下很有用赚导,例如茬缩,獲取對全局對象的引用(假設(shè)您在非瀏覽器環(huán)境中吼旧,window不是可用的)

(function () {
  'use strict';
  var global = (function () { return this || (1, eval)('this') })();
})();

在上面的代碼中,內(nèi)部匿名函數(shù)將在嚴(yán)格模式代碼單元內(nèi)執(zhí)行,這將導(dǎo)致this值為undefined

||運營商現(xiàn)在就第二個操作數(shù)的eval調(diào)用处面,這是一個間接調(diào)用,它將評估對全球詞法和環(huán)境變量的代碼菩掏。

但就我個人而言,在這種情況下智绸,在嚴(yán)格模式下,我更喜歡使用Function構(gòu)造函數(shù)來獲取全局對象:

(function () {
  'use strict'
  var global = Function('return this')()
})()

使用Function構(gòu)造函數(shù)創(chuàng)建的函數(shù)只有在以 use strict 指令開頭時才是嚴(yán)格的瞧栗,它們不像函數(shù)聲明或函數(shù)表達式那樣“繼承”當(dāng)前上下文的嚴(yán)格性

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市迹恐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌殴边,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锤岸,死亡現(xiàn)場離奇詭異,居然都是意外死亡是偷,警方通過查閱死者的電腦和手機拳氢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門馋评,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刺啦,你說我怎么就攤上這事『樵铮” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵捧韵,是天一觀的道長。 經(jīng)常有香客問我再来,道長蒙兰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任搜变,我火速辦了婚禮,結(jié)果婚禮上挠他,老公的妹妹穿的比我還像新娘扳抽。我一直安慰自己殖侵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布拢军。 她就那樣靜靜地躺著,像睡著了一般茉唉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上度陆,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音坚芜,去河邊找鬼览芳。 笑死斜姥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铸敏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼杈笔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蒙具?” 一聲冷哼從身側(cè)響起球榆,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤禁筏,失蹤者是張志新(化名)和其女友劉穎持钉,沒想到半個月后篱昔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體始腾,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡空执,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了辨绊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡门坷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拜鹤,到底是詐尸還是另有隱情框冀,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布明也,位于F島的核電站,受9級特大地震影響惯裕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜻势,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望握玛。 院中可真熱鬧,春花似錦挠铲、人聲如沸冕屯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓢棒。三九已至,卻和暖如春脯宿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗅绰。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工舍肠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翠语。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像肌括,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子谍夭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,652評論 2 354