var app = app || {}

看 TODOMVC 源代碼的時候辈讶,看到如下一段代碼:

var app = app || {};

https://github.com/tastejs/todomvc/blob/master/examples/backbone/js/models/todo.js#L2

很多次看到過類似的代碼,也大概明白這是怎么回事,可是底瓣,為啥要這么寫斯议,這么寫是怎么起作用的呢芒划?

在 StackOverflow 上,也有帶著類似困惑的小伙伴問了類似的問題哲思,這里:
http://stackoverflow.com/questions/6439579/what-does-var-foo-foo-assign-a-variable-or-an-empty-object-to-that-va
“標準答案”是這么解釋的:

Your guess as to the intent of || {} is pretty close.

This particular pattern when seen at the top of files is used to create a namespace, i.e. a named object under which functions and variables can be created without unduly polluting the global object.

The reason why it's used is so that if you have two (or more) files:

var MY_NAMESPACE = MY_NAMESPACE ||  {};
MY_NAMESPACE.func1 = {}

and

var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {}

both of which share the same namespace it then doesn't matter in which order the two files are loaded, you still get func1 and func2 correctly defined within the MY_NAMESPACE object correctly.

The first file loaded will create the initial MY_NAMESPACE object, and any subsequently loaded file willaugment the object.

Usefully, this also allows asynchronous loading of scripts that share the same namespace which can improve page loading times. If the <script> tags have the defer attribute set you can't know in which order they'll be interpreted, so as described above this fixes that problem too.

不過這個答案給出的是為啥要這么用,至于這么寫起作用的原理沒有介紹很多吩案。

單純看一處代碼:

var app = app || {};

這里涉及到變量的聲明和賦值棚赔。而變量的聲明涉及到“變量聲明提前”的問題,比如在一個函數(shù)中徘郭,無論變量是不是在函數(shù)的最開始聲明的靠益,變量都可以使用,例如:

function foo() {
  x = 'ok';
  console.log(x);
  var x; 
}

當然残揉,如果沒有最后的 var x; 聲明語句胧后,變量 x 就成了全局變量了。
并且抱环,在一個作用域下壳快,多次聲明同一變量纸巷,由于“變量聲明提前”的緣故,其實仍然是同一個變量眶痰。
這一部分的具體介紹見:《JavaScript 權威指南》(第6版) 5.3.1 var瘤旨。

回過頭來琢磨最開始的問題,之所以 var app = app || {} 能夠有效竖伯,應該是由于這些在不同文件中的語句存哲,最終是在同一作用域下執(zhí)行的。最終在該作用域(也就是全局作用域)下七婴,只有一個app變量祟偷。而||的作用,就是在app變量已有值的情況下本姥,直接返回已有的值肩袍,沒有值的情況下返回右側的空對象,從而確保app始終是非空的對象婚惫。
關于||的這種用法的具體介紹氛赐,請看:《JavaScript 權威指南》(第6版)4.10.2 邏輯或(||)。

那么先舷,如果這些語句不在同一作用域下執(zhí)行的話艰管,會怎樣呢?例如:

var app = app || {};
app.foo = 'foo';

(function () {
  var app = app || {};
  app.bar = 'bar';
})()

試驗一下蒋川,就會發(fā)現(xiàn)牲芋,上述代碼執(zhí)行完之后,app 對象還是沒有屬性 bar 的捺球。

為什么呢缸浦?
簡單來說,因為函數(shù)內(nèi)的 app 是個內(nèi)部變量氮兵,與外部的 app 互不影響裂逐。

再把上面的例子改寫下:

var app = app || {};
app.foo = 'foo';

(function () {
  app.bar = 'bar';
  var app = app || {};
})()

這樣的話又如何呢?這次是不是代碼執(zhí)行后外部的 app 有了屬性 bar 了呢泣栈?

執(zhí)行一下的話會發(fā)現(xiàn)卜高,居然報錯了!

Uncaught TypeError: Cannot set property 'bar' of undefined

仔細琢磨下....其實還是“變量聲明提前”在搞鬼南片。函數(shù)內(nèi)部的變量 app 的聲明提前了掺涛,但是賦值語句不會提前。沒有賦值的變量的值是什么呢疼进?是 undefined 的薪缆。這里的錯誤說清楚了吧,因為此時的 app 是函數(shù)內(nèi)部的私有變量颠悬,還沒有賦值矮燎。為啥不是外面的 app 呢定血,因為函數(shù)內(nèi)部聲明了同名的 app,而通過“變量聲明提前”诞外,函數(shù)內(nèi)的 app 都是指向內(nèi)部的變量的澜沟。

小結

其實像這里分析的代碼,在日常工作中會看到很多峡谊,大致是怎么回事是清楚的茫虽,可是真的要去詳細解釋為啥這么做,這么做又是為啥會起作用既们,可能就懵了濒析。

編程這件事好像特別看重細節(jié),畢竟無論多么 NB 的應用啥纸,也都是一行行代碼構建起來的号杏。細節(jié)上不清楚,很可能會出現(xiàn)一些習以為常到反而看不出來的小 bug斯棒,這樣的東西多了盾致,問題也就大了。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荣暮,一起剝皮案震驚了整個濱河市庭惜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌穗酥,老刑警劉巖护赊,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砾跃,居然都是意外死亡骏啰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門抽高,熙熙樓的掌柜王于貴愁眉苦臉地迎上來器一,“玉大人,你說我怎么就攤上這事厨内。” “怎么了渺贤?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵雏胃,是天一觀的道長。 經(jīng)常有香客問我志鞍,道長瞭亮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任固棚,我火速辦了婚禮统翩,結果婚禮上仙蚜,老公的妹妹穿的比我還像新娘。我一直安慰自己厂汗,他們只是感情好委粉,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著娶桦,像睡著了一般贾节。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衷畦,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天栗涂,我揣著相機與錄音,去河邊找鬼祈争。 笑死斤程,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的菩混。 我是一名探鬼主播忿墅,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼墨吓!你這毒婦竟也來了球匕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤帖烘,失蹤者是張志新(化名)和其女友劉穎亮曹,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秘症,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡照卦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乡摹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片役耕。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖聪廉,靈堂內(nèi)的尸體忽然破棺而出瞬痘,到底是詐尸還是另有隱情,我是刑警寧澤板熊,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布框全,位于F島的核電站,受9級特大地震影響干签,放射性物質發(fā)生泄漏津辩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喘沿。 院中可真熱鬧闸度,春花似錦、人聲如沸蚜印。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晒哄。三九已至睁宰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寝凌,已是汗流浹背柒傻。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留较木,地道東北人红符。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像伐债,于是被迫代替她去往敵國和親预侯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容