Javascript的腦洞(一)

2021-09-11 10:29:50 字數 2560 閱讀 3962

無窮大的數

var a = 12 / 0

if (a== infinity)

既然js的變數實際都是某種引用(存放物件的位址),那麼a這個名字的背後可以存放任意東西,包括無窮大這個值。但是js在這裡直接違背了數學規律,讓0除的結果變成無窮大,真實腦洞大開!如果設計成nan值,也更好理解吧?

undefined被定義

undefined是個特殊物件,這個物件未定義型別和值。我們通過undefined這個控制代碼來抓住和引用它。

var a;

if (a==undefined)

js似乎忘記把undefined放進關鍵字列表,因此我們重新定義undefined這個控制代碼。

function joke() 

}joke()

解決辦法是使用void expr。void是個運算子,會計算expr表示式的值,但是void表示式返回的是真正undefined對應的物件引用。

function joke() 

}joke()

函式內定義函式

var x = 10;

function foo()

function out()

out()

這一段**列印出10,而不是20。根據c語言經驗,雖然var x=20干擾了一下視線,但那時區域性變數,foo函式看不到。這非常符合c的常識。但是下面**,讓熟悉c語言的人撓頭了:

var x = 10;

function out()

foo();

}out()

**輸出20,正好是區域性變數var x=20. 這涉及到作用域鏈(scope chain)這個概念。foo函式跑在out這個大環境下,out跑在全域性這個最大環境下。區域性環境自然會受到大環境影響。正如村里的環境受國內環境影響,國內環境受國際環境影響一樣。js的一大特點就是函式內定義函式這乙個腦洞大開的想法。因為萬物皆物件,函式本身也是一種特殊的物件。所以,foo就是函式背後物件的識別符號。foo物件有乙個屬性,名字是[[scope]]。foo.[[scope]] = [ vo陣列 ];那麼vo(變數物件variable object)是什麼?vo是乙個物件,存放變數的識別符號有關的資訊。foo.[[scope]] = [  out的vo,  global的vo ]。因為foo的外層環境是out,再外層環境是global,所以,這個陣列就反應了這個關係。而且,一旦解析器分析了**,這個環境關係就是確定的,與呼叫堆疊(函式之間呼叫關係)毫無關係。所以,foo.[[scope]] 是靜態的不變的。當真正呼叫函式foo時,需要乙個輔助性的物件(名字叫做execution context執行上下文,簡稱ec物件)用於幫助執行**。fooec物件的偽**看起來像這樣:

fooec = ,

this: ...

scope: [ foovo, outvo, globlevo ]

}outvo =

globlevo =

當foo函式執行時遇到x,就在fooec.scope中查詢x,顯然foovo中沒有,幸運的是outvo中存在x,因此就是20了。

全域性變數隨意建立

function foo() 

foo()

console.log(this.y);

如果未指定var,y=30建立了乙個全域性變數golbal的屬性y。this指向全域性變數global, 因此this.y==global.y==30

準備和執行,請掃瞄兩遍

閱讀js**時,為了穩妥起見,請人肉掃瞄兩遍**。第一遍,建立一些神秘的概念物件,幫助思考第二遍的掃瞄。

function f() ;

f();

var a = 10; // 全域性上下文中的變數

console.log(b); // referenceerror: b is not defined

執行這段簡單的**前,要先準備執行環境,相關資訊放到叫做執行環境物件的地方。假設此物件為:

globalec = ,  //存放自定義的函式,var變數等

this = global,//存放的是this指向的物件

scope =  [globalvo] //存放作用域鍊錶(用陣列模擬),用於依次在裡面搜尋變數

}萬物皆物件,實際上f,a都是全域性物件global的屬性,而不是自由的存在。

//begin vo  

var a ;

//end vo

function f() ;

f();

a = 10;

console.log(b); // referenceerror: b is not defined

這個方法叫做變數提公升hoisting。也許是有益的一種程式設計風格,避免了每次閱讀**人肉提公升變數,或者幻想ec物件。

開啟你的腦洞

我的大學是在北京師範大學讀的,當時讀的乙個叫做 勵耘實驗班 的專業 現在已經取消了 美其名曰第一年進行通識教育,第二年選專業。我最終選擇了計算機專業,並且有幸和一群不同專業的室友一起生活了四年。其中乙個室友選了 數字 專業,他在專業學習過程中,需要每天看各種電影,分析各種電影片段的拍攝手法。那個時候...

腦洞大開的睡眠排序

睡眠排序演算法,嘻嘻,本身只是乙個腦洞開啟的排序演算法。排序演算法一般是力求兼顧時間和空間的平衡,而睡眠排序演算法卻像是乙個玩笑,當時間和空間兩者消耗足夠大,才能達到最終精確排序的目的。實現原理 構造 n 個執行緒,它們和這 n 個數一一對應。初始化後,執行緒們開始睡眠,等到對應的數那麼多個時間單位...

腦洞 整體分塊 BSGS

ran 讓 ei 刷整體二分的題,並且丟給 ei 一道 zjoi2013 k大數查詢。但是 ei 並不想寫整體二分。也不想寫資料結構。於是一拍腦門,就有了這個奇怪的想法。大致思路 對於 c cc 先離散化,然後考慮乙個類似 bsgs 的找答案的過程 將從大到小的 c cc 分成 m sqrt m m...