中文字幕日韩一区二区_国产一区二区av_国产毛片av_久久久久国产一区_色婷婷电影_国产一区二区精品

對JavaScript的eval()中使用函數(shù)的進(jìn)一步討論

var func = eval("(function(){})");
alert(typeof func);
--------
更進(jìn)一步的問題是,書中對匿名和具名函數(shù)在JScript與SpiderMonkey中的表現(xiàn)解釋得不夠
清楚。好的,這篇文章就這個問題深入討論,不單涉及書中的內(nèi)容,也更深入地講述一
下JS的解釋與執(zhí)行過程――其實(shí)所有的內(nèi)容在書中都有涉及,但過于分散,不便于專門
地來分析一個具體問題。

首先,應(yīng)該明確表達(dá)式與語句。對于JS來說,eval()總是試圖執(zhí)行一個語句,因此它必須
先將執(zhí)行文本理解為語句。如下:
--------
eval("1")
--------
在JS看來,由于eval()必須執(zhí)行語句,因此"1"不再是直接量表達(dá)式,而是直接量表達(dá)式語
句,也就是相當(dāng)于“1;”。這些內(nèi)容,在“5.2.2  動態(tài)執(zhí)行過程中的語句、表達(dá)式與值”
中有詳細(xì)解釋。

所以,eval()的返回值,其實(shí)是語句最后一個(有效的)子句的返回值。接下來,我們需
要了解“聲明語句”和“表達(dá)式”。例如:
--------
function x() {
  //....
}
--------
很明顯,這是一個具名函數(shù)的“聲明語句”。注意的是,“聲明語句”是不返回值的。也
就是說,聲明語句是在語法解釋期,由預(yù)編譯器處理的,而在執(zhí)行期它是沒意義的――沒
有值,也沒有返回值。例如單純的“var X”,是一個聲明語句,它就不會返回值,而對于
“var X=100”來說,JS就處理成一個聲明語句,和一個在執(zhí)行期的賦值語句,它就有返回
值(后者的值)。

上面的規(guī)則對于JScript和SpiderMonkey來說都是一樣的,這沒有區(qū)別。有區(qū)別的是接下來的
內(nèi)容。首先,SpiderMonkey承認(rèn)“函數(shù)表達(dá)式(function expression)”,為了直接這樣一種
特性,它約在“函數(shù)表達(dá)式”中出現(xiàn)的“函數(shù)名”是無效的。因?yàn)椤昂瘮?shù)名”是“聲明語
句”來陳述的,而“表達(dá)式”是比語句更小(或更低級)的一個級別,因此不可能在“表
達(dá)式”中出現(xiàn)“語句聲明”,所以只好在表達(dá)式中忽略函數(shù)名。這樣一來,SpiderMonkey中
下面語句:
--------
x = "1234" + (function X() {});
------
中函數(shù)X就沒有標(biāo)識符的效果,它對表達(dá)式之外的、或者全局的“標(biāo)識符”都不會構(gòu)成影
響。更進(jìn)一步地說:
--------
var X = 100;
x = "1234" + (function X() {});
------
在這樣兩行代碼中,變量X不會被重寫,因?yàn)榈诙兄械暮瘮?shù)名X是無效的。關(guān)于這些內(nèi)
容,在書中“5.4.2.1  語法聲明與語句含義不一致的問題”有詳細(xì)解釋。

正是在上面這個小節(jié)中,還討論到了MS JScript對這個問題的處理。JScript承認(rèn)在代碼內(nèi)文
的任意位置出現(xiàn)的函數(shù)標(biāo)識符聲明。也就是說,由于上面的標(biāo)識符是有效的,所以全局變
量中的“X”就會被重寫。但是,正是由于這個緣故,JScript就必須對下面這個問題做解釋:
------
eval("(function(){})");
eval("(function X(){})");
------
請問:這兩行代碼在語義上有沒有不同?由于SpiderMonkey承認(rèn)函數(shù)表達(dá)式,因此把兩個
都解釋為表達(dá)式的運(yùn)算元;而JScript要承認(rèn)第二行代碼中的變量名X,因此只好兩個都解釋
為語句。也就是說,在缺省情況下,JScript認(rèn)為第一行是匿名函數(shù)“聲明語句”,第二行則
是具名函數(shù)聲明語句。因此,如同前面所說的,“聲明語句”不返回值,所以在JScript中兩
行代碼都返回undefined,而且第二行代碼聲明了一個變量名X。

關(guān)于這個問題,我在腳注中說“函數(shù)聲明的語句含義”的確是有些含糊的。無論如何,只需
要簡單地理解為JScript認(rèn)為這里是“函數(shù)語句聲明”,而SpiderMonkey認(rèn)為這里是“函數(shù)表達(dá)
式聲明”就可以了。

好。到這里為止,我們大概只解釋清楚了:
------
eval("(function(){})");
eval("(function X(){})");
------
這兩行語句的效果,以及產(chǎn)生這種效果的原因。但是,對于我在書上的例子和腳注說明,仍
然是有疑問的。這來源于這段文字和代碼:
------
不過在JScript中存在一個例外:函數(shù)直接量(這里指匿名函數(shù))不能通過這種方式來獲得。例如下面的代碼:
var func = eval("(function() { })");
// 輸出"undefined"
alert(typeof func);
這種情況下,可以具名函數(shù)來得到它(*)。例如:………………
------
先留意這段文字是上下文相關(guān)的。我只是想說明如何能向變量"func"賦一個有效的值。這涉
及到兩種方法:
------
// 方法1,用匿名函數(shù)
var func = eval("(function() { })");
alert(typeof func);

// 方法2,用具名函數(shù)
var func;
eval("function func() { }");
alert(typeof func);
------
這段話的意思是“在JScript中使用方法1(用匿名函數(shù)的方法)是不行的,需要使用第二種”,
而在腳注中,說SpiderMonkey正好相反,也僅指這個例子而言――在SpiderMonkey中,第
二種方法是無效的,而第一種是有效的。

這里與前述的內(nèi)容稍有差異的是,方法2并沒有使用“返回值”,而只是通過eval()語句中
利用函數(shù)名聲明的效果,來影響全局變量func。而正是由于SpiderMonkey不承認(rèn)這個聲明的
標(biāo)識符,所以是無效的。

同樣的原因,讀者I22141說修改成下面這樣:
------
var func = eval("function func() { }");
------
在SpiderMonkey中則是利用了返回值,與上面這個示例已經(jīng)不是同一個問題了。所以I22141
所問“(那么你所說的在SpiderMonkey中可以用eval()返回一個匿名函數(shù),而對具名函數(shù)卻只
能返回undefined是什么含義?)”,也是脫離了這個示例的一個設(shè)問。

最后再來講述一個細(xì)節(jié)問題,這在書上也未有提及,其實(shí)也是一個很怪異的事件。首先,在
上面我說,在JScript中:
--------
// 第一種情況
var func = eval("(function(){})");
alert(typeof func); // 顯示"undefined"
--------
這里顯示undefined是因?yàn)镴Script將后面的函數(shù)解釋為匿名函數(shù)聲明,所以沒有值。其實(shí)是相對
要牽強(qiáng)一些的。因?yàn)槲覀冃薷囊幌拢?
--------
// 第二種情況
var func = eval("(1, function(){})");
alert(typeof func);  // 顯示"function"
--------
就不同了。那么到底為什么第一種情況下,JScript就一定是理解為“聲明語句”而不是表達(dá)
式呢?我不得確知。我只是從:
--------
// 第三種情況
var X;
eval("(function X(){})");
alert(typeof X); // 顯示"function"
--------
這種情況下存在“語句聲明”的效果來推斷第一種情況的。更為奇特的是,我不清楚為什
么JScript容許在一個表達(dá)式運(yùn)算符“(...)”中存在一個“語句”――因?yàn)槔碚撋险f,這種情
況是在語法分析中難于解釋的。我甚至在“5.4.2.1  語法聲明與語句含義不一致的問題”提
到下面的代碼:
--------
// 示例5:語法聲明階段重寫
// 重寫
(function Object(){
}).prototype.value = 100;

// 顯示值undefined
var obj = new Object();
alert(obj.value);
--------
是因?yàn)閳?zhí)行期“(X).prototype.value”中的那個函數(shù)X,與語句分析期覆蓋了全局的Object標(biāo)識
符的函數(shù),不是同一個。但,我仍然不明白,為什么JScript允許在表達(dá)式中存在聲明語句。
與此更為相悖的是,如果要承認(rèn)這樣的假設(shè),那么為什么下面的語句不能執(zhí)行:
--------
(var x=100);
--------
然而如果不承認(rèn),那么下面的代碼卻又能正常執(zhí)行:
--------
(function X() {});
--------
OH... 在這個問題的最終答案上,我仍然是迷惑的。

JavaScript技術(shù)對JavaScript的eval()中使用函數(shù)的進(jìn)一步討論,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 成年人国产在线观看 | 成人h视频在线 | 色视频网站| 少妇特黄a一区二区三区88av | 欧美三级在线 | 精品国产1区2区3区 一区二区手机在线 | 粉嫩在线 | 欧美日韩精品一区二区三区视频 | 欧美成年人网站 | 免费精品一区 | 国产一区二区三区日韩 | 国产视频在线一区二区 | sese视频在线观看 | 九色网址 | 国产精品美女久久久久久不卡 | 久日精品 | 产真a观专区 | 国产福利91精品 | 亚洲黄色片免费观看 | 久久久久国产一级毛片高清网站 | 欧美啊v在线观看 | 午夜影院网站 | 亚洲一区二区日韩 | 偷牌自拍 | 精品在线一区二区 | 成人国产免费视频 | 欧美操操操 | av网站在线免费观看 | 久久一区二区免费视频 | 一区二区三区精品视频 | 日韩一区二区在线观看视频 | 青青草综合网 | 欧美精品一二区 | 婷婷精品 | 97色在线视频| 国产在线精品一区二区 | 久久在线| 亚洲网站在线播放 | 91黄色片免费看 | 免费看国产一级特黄aaaa大片 | 久久久久久久久久久久久九 |