2014-10-31 44 views
0

本書JavaScript for PHP Developers包含我添加警報()■顯示下面的註釋代碼(以 單變量表達式語句形式「JavaScript的PHP開發 - >內置的API - >全局對象」:在瀏覽器中無法重現的代碼

variable; 

和 的價值觀,我還增加了「使用嚴格的」指令來看看這是什麼 導致的問題。我無法重現code on JSFiddle與Firefox。 我已將自己的評論添加到大寫字母代碼中:

'use strict'; 

// Create a global variable 
var john = "Jo"; 
alert(john);  // "Jo" 
alert(window.john); // "Jo", works as a property too 
        /* BUT I GET UNDEFINED HERE */ 
// Create a property of the global object 
window.jane = "JJ"; 
alert(jane);  // "JJ", works as a variable too 
alert(window.jane); // "JJ" 

// Delete them 
alert(delete window.john); // false 
          /* BUT I GET true HERE */ 
alert(delete window.jane); // true 

alert(john); // "Jo" 
alert(jane); // undefined 
      /* BUT PROGRAM CRASHES HERE */ 
alert(this === window); // true 

實際上在following small program最後警報函數調用從未達到:

window.jane = "JJ"; 
delete window.jane; 
alert(jane); // Program Crashes 
alert('Got Here'); 

我測試過的所有案件在這裏再一次這說明所有情況。

var a = 'John'; 
window.b = 'Jane'; 
c = 'Jack'; 

alert(a); // John 
alert(b); // Jane 
alert(c); // Jack 

alert(window.a); // undefined 
alert(window.b); // Jane 
alert(window.c); // Jack 

alert(delete a); // false 
alert(delete b); // true 
alert(delete c); // true 

alert(a); // John 
//alert(b); // would crash 
//alert(c); // would crash 

window.b = 'Jane'; 
c = 'Jack'; 

alert(delete window.a); // true 
alert(delete window.b); // true 
alert(delete window.c); // true 

alert(window.a); // undefined 
alert(window.b); // undefined 
alert(window.c); // undefined 

alert(a); // John 
//alert(b); // would crash 
//alert(c); // would crash 

我想知道的是,這種行爲在所有瀏覽器 或者是一個瀏覽器和其他之間的差異是一致的。 本書的代碼是否有錯,或者是否僅僅是針對不同於我自己的(Firefox 33.0.1)的 運行的瀏覽器?

如果有人能夠解釋各種情況,可能指向ECMA規範的相關 部分,將不勝感激。

謝謝。


OK,我看到的結果是這樣的,因爲我已經運行的jsfiddle裏面的代碼 在onload功能,而不是在全球範圍內,如指出。在我的本地機器上運行的網頁內部運行綜合測試的結果爲 。 上JSFiddle with the script inside the body html element的結果是一樣的:

<!DOCTYPE html> 
<html> 
<head> 
<title></title> 
</head> 
<body> 
<script type="text/javascript"> 
var a = 'John'; 
window.b = 'Jane'; 
c = 'Jack'; 

alert(a); // John 
alert(b); // Jane 
alert(c); // Jack 

alert(window.a); // John 
alert(window.b); // Jane 
alert(window.c); // Jack 

alert(delete a); // false 
alert(delete b); // true 
alert(delete c); // true 

alert(a); // John 
try { alert(b); } catch (e) { alert(e); } // throws ReferenceError: b is not defined 
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined 

window.b = 'Jane'; 
c = 'Jack'; 

alert(delete window.a); // false 
alert(delete window.b); // true 
alert(delete window.c); // true 

alert(window.a); // John 
alert(window.b); // undefined 
alert(window.c); // undefined 

alert(a); // John 
try { alert(b); } catch (e) { alert(e); } // throws ReferenceError: b is not defined 
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined 
</script> 
</body> 
</html> 

here is what happens when the ECMAScript5 'use strict' directive is also used。雖然 我知道在嚴格模式下聲明一個沒有var的變量會導致引用錯誤 我不確定我能否理解其餘的輸出,特別是爲什麼腳本 在某些地方終止執行:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title></title> 
</head> 
<body> 
<script type="text/javascript"> 
'use strict'; 

var a = 'John'; 
window.b = 'Jane'; 
try { c = 'Jack'; } catch (e) { alert(e); } // throws ReferenceError: assignment to undeclared variable c 

alert(a); // John 
alert(b); // Jane 
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined 

alert(window.a); // John 
alert(window.b); // Jane 
alert(window.c); // undefined 

try { 
// Uncommenting any of these three following statements will cause the script to be exited 
// during the parsing time; no statement from this script will be executed. 
//alert(delete a); causes script to end during parsing at runtime even though try catch block present 
//alert(delete b); causes script to end during parsing at runtime even though try catch block present 
//alert(delete c); causes script to end during parsing at runtime even though try catch block present 
} catch (e) { alert(e); } 

alert(a); // John 
try { alert(b); } catch (e) { alert(e); } // Jane 
try { alert(c); } catch (e) { alert(e); } // throws ReferenceError: c is not defined 

window.b = 'Jane'; 
c = 'Jack'; 

try { 
//alert(delete window.a); // causes script to end during execution at runtime even though try catch block present 
//alert(delete window.b); // causes script to end during execution at runtime even though try catch block present 
//alert(delete window.c); // causes script to end during execution at runtime even though try catch block present 
} catch (e) { alert(e); } 

/* Script stops execution at this point. Why????? 

alert(window.a); // 
alert(window.b); // 
alert(window.c); // 

alert(a); // 
try { alert(b); } catch (e) { alert(e); } // 
try { alert(c); } catch (e) { alert(e); } // 
</script> 
</body> 
</html> 

如果任何人都可以幫我解釋爲什麼腳本執行終止在某些地方 他們做嚴格模式的方式將不勝感激。

謝謝。


至於從書,origninal代碼時從文件的頭部的腳本 標籤內正常運行,我得到下面的輸出,是我們可以看到, 的ReferenceError例如由於訪問變量jane被拋出。 Here is the JSFiddle for the code

//'use strict' 

// Create a global variable 
var john = "Jo"; 
alert(john);  // "Jo" 
alert(window.john); // "Jo", works as a property too 

// Create a property of the global object 
window.jane = "JJ"; 
alert(jane);  // "JJ", works as a variable too 
alert(window.jane); // "JJ" 

// Delete them 
try { alert(delete window.john); } catch (e) { alert(e); } 
// false 
/* if strict mode were enforced would actually cause 
    the following fatal error: 
    TypeError: 
    property "john" is non-configurable and can't be deleted 
*/ 
try { alert(delete window.jane); } catch (e) { alert(e); } 
// true 

alert(john); // "Jo" 
try { alert(jane); } catch (e) { alert(e); } // undefined in book 
/* but actually gives a: 
    ReferenceError: jane is not defined 
    which is a fatal error causing the script to exit 
    if not caught*/ 
alert(this === window); // true 
+3

我懷疑這隻發生在JSFiddle上,對吧?如果是這樣,那是因爲JSFiddle將你的JS代碼封裝在'onload'函數中。 – 2014-10-31 12:46:55

+1

請仔細閱讀這些文檔:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var和here:https://developer.mozilla.org/en-US/ docs/Web/JavaScript/Reference/Strict_mode – istos 2014-10-31 12:56:38

+0

謝謝@istos的參考。有一件事我沒有得到。關於第一個鏈接,可配置屬性和不可配置屬性之間有什麼區別。謝謝。 – 2014-10-31 14:49:51

回答

1

看看界面的這一部分的jsfiddle:

jsfiddle screenshot

那「的onLoad」選擇意味着你鍵入到接口的JavaScript的象限的代碼將被包裝在你的函數中,並且該函數將作爲窗口的「加載」事件處理程序。因爲你的代碼是在一個函數中,所以你聲明的變量出現在是全球級別真的不是全局的;它們是函數中的局部變量。

要使您的代碼真正成爲全局代碼,請將該選擇更改爲「無包裝」設置之一。

+0

謝謝@Pointy您的回覆。我相應地更新了我的帖子。 – 2014-10-31 14:50:19

+0

是的,至少是「var a;」語句聲明瞭一個局部變量(一個帶有函數作用域的變量)而不是一個全局變量。 – 2014-10-31 18:29:23

+0

@JohnSonderson關於你的其他問題,在腳本的任何部分執行之前,所有分析時錯誤都會發生(獨立於嚴格模式的工作方式)。這就是爲什麼他們不能被'try/catch'封裝捕獲的原因。特別是'alert(delete a)'是嚴格模式下的語法錯誤,因爲直接引用'delete'表達式中的變量名稱是在解析時識別的,而不是運行時識別的。 – Pointy 2014-10-31 18:35:07

相關問題