本章是 ECMAScript 規格標準化的全域變數的參考。Web 瀏覽器有更多全域變數,這些變數列於 MDN。所有全域變數都是全域物件的(自有或繼承的)屬性(瀏覽器中的window
;請參閱全域物件)。
Array
(陣列建構函式)
Boolean
(基本資料型別的包裝物件)
Date
(日期建構函式)
Function
(使用 new Function() 評估程式碼)
Number
(基本資料型別的包裝物件)
Object
(將任何值轉換為物件)
RegExp
(建立正規表示法)
String
(基本資料型別的包裝物件)
Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError
encodeURI(uri)
百分比編碼uri
中的特殊字元。特殊字元是所有 Unicode 字元,但下列字元除外
URI 字元 |
|
也不編碼 |
|
例如
> encodeURI('http://example.com/Für Elise/') 'http://example.com/F%C3%BCr%20Elise/'
encodeURIComponent(uriComponent)
百分比編碼 uriComponent
中的所有字元,但下列字元除外
未編碼 |
|
與 encodeURI
相反,URL 和檔案名稱中重要的字元也會被編碼。因此,您可以使用此函式將任何文字轉換為合法的檔案名稱或 URL 路徑區段。例如
> encodeURIComponent('http://example.com/Für Elise/') 'http%3A%2F%2Fexample.com%2FF%C3%BCr%20Elise%2F'
decodeURI(encodedURI)
解碼由 encodeURI
產生的百分比編碼 URI
> decodeURI('http://example.com/F%C3%BCr%20Elise/') 'http://example.com/Für Elise/'
encodeURI
沒有編碼 URI 字元,而 decodeURI
沒有解碼 URI 字元,即使它們已正確編碼
> decodeURI('%2F') '%2F' > decodeURIComponent('%2F') '/'
decodeURIComponent(encodedURIComponent)
解碼由 encodeURIComponent
產生的百分比編碼 URI 組件。與 decodeURI
相反,所有百分比編碼字元都會被解碼
> decodeURIComponent('http%3A%2F%2Fexample.com%2FF%C3%BCr%20Elise%2F') 'http://example.com/Für Elise/'
下列項目已不建議使用
escape(str)
百分比編碼 str
。它已不建議使用,因為它無法正確處理非 ASCII 字元。請改用 encodeURIComponent()
。
unescape(str)
百分比解碼 str
。它已不建議使用,因為它無法正確處理非 ASCII 字元。請改用 decodeURIComponent()
。
下列方法有助於分類和剖析數字:
isFinite(number)
(檢查無限大)
isNaN(value)
(陷阱:檢查值是否為 NaN)
parseFloat(string)
(parseFloat())
parseInt(string, radix)
(透過 parseInt() 取得整數)
函式呼叫:
eval
(
str
)
評估 str
中的 JavaScript 程式碼。例如
> var a = 12; > eval('a + 5') 17
請注意,eval()
會在陳述式內容中剖析 (請參閱 表達式與陳述式)
> eval('{ foo: 123 }') // code block 123 > eval('({ foo: 123 })') // object literal { foo: 123 }
對於 eval()
,您真的應該使用嚴格模式 (請參閱 嚴格模式)。在草率模式中,評估的程式碼可以在周圍的範圍中建立局部變數
function
sloppyFunc
()
{
eval
(
'var foo = 123'
);
// added to the scope of sloppyFunc
console
.
log
(
foo
);
// 123
}
嚴格模式下無法發生
function
strictFunc
()
{
'use strict'
;
eval
(
'var foo = 123'
);
console
.
log
(
foo
);
// ReferenceError: foo is not defined
}
然而,即使在嚴格模式下,已評估的程式碼仍有讀取和寫入權限,可存取周圍範圍內的變數。若要防止此類存取,您需要間接呼叫 eval()
。
有兩種 呼叫 eval()
的方式:
call()
,作為 window
的方法,將其儲存在不同的名稱下並在那裡呼叫它,等等)。
正如我們已經看到的,直接 eval()
會在目前的範圍內執行程式碼
var
x
=
'global'
;
function
directEval
()
{
'use strict'
;
var
x
=
'local'
;
console
.
log
(
eval
(
'x'
));
// local
}
相反地,間接 eval()
會在全域範圍內執行程式碼
var
x
=
'global'
;
function
indirectEval
()
{
'use strict'
;
var
x
=
'local'
;
// Don’t call eval directly
console
.
log
(
eval
.
call
(
null
,
'x'
));
// global
console
.
log
(
window
.
eval
(
'x'
));
// global
console
.
log
((
1
,
eval
)(
'x'
));
// global (1)
// Change the name of eval
var
xeval
=
eval
;
console
.
log
(
xeval
(
'x'
));
// global
// Turn eval into a method
var
obj
=
{
eval
:
eval
};
console
.
log
(
obj
.
eval
(
'x'
));
// global
}
(1) 的說明:當您透過變數名稱參照變數時,初始結果是一個所謂的 參考,一個具有兩個主要欄位資料結構
base
指向 環境,儲存變數值的資料結構。
referencedName
是變數的名稱。
在 eval()
函式呼叫期間,函式呼叫運算子(括號)會遇到對 eval
的參考,並可以確定要呼叫的函式名稱。因此,此類函式呼叫會觸發直接 eval()
。但是,您可以透過不給呼叫運算子參考來強制間接 eval()
。這是在套用運算子之前擷取參考值的同時實現的。逗號運算子在第 (1) 行中為我們執行此操作。此運算子會評估第一個運算元,並傳回評估第二個運算元的結果。評估總是會產生值,這表示會解析參考,並遺失函式名稱。
間接評估的程式碼總是會很隨意。這是因為程式碼會獨立於其目前的環境進行評估
function
strictFunc
()
{
'use strict'
;
var
code
=
'(function () { return this }())'
;
var
result
=
eval
.
call
(
null
,
code
);
console
.
log
(
result
!==
undefined
);
// true, sloppy mode
}
建構函式 Function()
有簽章:
new
Function
(
param1
,
...,
paramN
,
funcBody
)
它建立一個函式,其零個或多個參數具有名稱 param1
、parem2
等,且其主體為 funcBody
;換句話說,建立的函式看起來像這樣
function
(
«
param1
»
,
...,
«
paramN
»
)
{
«
funcBody
»
}
讓我們使用 new Function()
建立一個函式 f
,其傳回其參數的總和
> var f = new Function('x', 'y', 'return x+y'); > f(3, 4) 7
類似於間接 eval()
,new Function()
建立的函式其範圍是全域的:[18]
var
x
=
'global'
;
function
strictFunc
()
{
'use strict'
;
var
x
=
'local'
;
var
f
=
new
Function
(
'return x'
);
console
.
log
(
f
());
// global
}
此類函式預設也是隨意的
function
strictFunc
()
{
'use strict'
;
var
sl
=
new
Function
(
'return this'
);
console
.
log
(
sl
()
!==
undefined
);
// true, sloppy mode
var
st
=
new
Function
(
'"use strict"; return this'
);
console
.
log
(
st
()
===
undefined
);
// true, strict mode
}
通常,使用 new Function()
比 eval()
來評估程式碼會更好:函式參數提供一個明確的介面來評估程式碼,而且您不需要間接 eval()
略顯尷尬的語法來確保評估的程式碼只能存取全域變數(除了它自己的變數)。
您應該避免 eval()
和 new Function()
。動態評估程式碼很慢,而且有潛在的安全風險。它也防止大多數使用靜態分析的工具(例如 IDE)考慮程式碼。
通常有更好的替代方案。例如,Brendan Eich 最近 推文一個反模式,由想要存取其名稱儲存在變數 propName
中的屬性的程式設計師使用
var
value
=
eval
(
'obj.'
+
propName
);
這個想法有道理:點運算子僅支援固定的、靜態提供的屬性鍵。在這種情況下,屬性鍵僅在執行時才知道,這就是為什麼需要 eval()
來使用該運算子的原因。幸運的是,JavaScript 也有方括號運算子,它接受動態屬性鍵。因此,以下是前述程式碼的更好版本
var
value
=
obj
[
propName
];
您也不應該使用 eval()
或 new Function()
來剖析 JSON 資料。那是危險的。請依賴 ECMAScript 5 內建的 JSON 支援(請參閱 第 22 章)或使用函式庫。
對於 eval()
和 new Function()
有一些正當的、儘管進階的使用案例:具有函式的組態資料(JSON 不允許)、範本函式庫、直譯器、命令列和模組系統。
這是動態評估 JavaScript 中程式碼的相對高階概觀。如果您想深入探討,您可以看看 kangax 的文章 “全域 eval。有哪些選項?”。
本部分概述了主控台 API。它记录了 Chrome 32、Firebug 1.12、Firefox 25、Internet Explorer 11、Node.js 0.10.22 和 Safari 7.0 中的现状。
主控台 API 的实现差异很大,并且不断变化。如果您需要权威的文档,则有两个选择。首先,您可以查看 API 的类标准概述:
其次,您可以查看各个引擎的文档
Internet Explorer 9 中有一个错误。在该浏览器中,console
对象仅在开发人员工具至少打开过一次时才存在。这意味着如果您引用 console
而之前并未打开该工具,则会收到 ReferenceError
。作为解决方法,您可以检查 console
是否存在,如果不存在,则创建一个虚拟实现。
主控台 API 包含以下 记录方法:
console.clear()
console.debug(object1, object2?, ...)
console.log()
,它与该方法执行相同操作。
console.error(object1, object2?, ...)
console.exception(errorObject, object1?, ...])
[仅限 Firebug]
object1
等,并显示交互式堆栈跟踪。
console.info(object1?, object2?, ...)
console.log(object1?, object2?, ...)
將參數記錄到主控台。如果第一個參數是 printf
格式的字串,請使用它來列印剩餘的參數。例如 (Node.js REPL)
> console.log('%s', { foo: 'bar' }) [object Object] > console.log('%j', { foo: 'bar' }) {"foo":"bar"}
唯一可靠的跨平台格式化指令是 %s
。Node.js 支援 %j
將資料格式化為 JSON;瀏覽器傾向支援將某些互動內容記錄到主控台的指令。
console.trace()
console.warn(object1?, object2?, ...)
下列表格指出在各種平台上的支援狀況
Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | ✓ | ✓ | ✓ | ||
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | |||||
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
exception
已以斜體排版,因為它僅在單一平台上受支援。
主控台 API 包含下列檢查和計數方法:
console.assert(expr, obj?)
expr
為 false
,請將 obj
記錄到主控台並擲回例外。如果它是 true
,則不執行任何動作。
console.count(label?)
下列表格指出在各種平台上的支援狀況
Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ |
主控台 API 包含下列用於格式化記錄的方法
console.dir(object)
console.dirxml(object)
console.group(object1?, object2?, ...)
console.groupEnd()
來關閉區塊。區塊最初會展開,但可以摺疊。
console.groupCollapsed(object1?, object2?, ...)
console.group()
,但區塊最初會摺疊。
console.groupEnd()
console.group()
或 console.group
Collapsed()
開啟的群組。
console.table(data, columns?)
將陣列列印成表格,每一列一個元素。選用參數 columns
指定在欄中顯示哪些屬性/陣列索引。如果遺漏該參數,則所有屬性鍵都會用作表格欄。遺漏的屬性和陣列元素會在欄中顯示為 undefined
var
persons
=
[
{
firstName
:
'Jane'
,
lastName
:
'Bond'
},
{
firstName
:
'Lars'
,
lastName
:
'Croft'
,
age
:
72
}
];
// Equivalent:
console
.
table
(
persons
);
console
.
table
(
persons
,
[
'firstName'
,
'lastName'
,
'age'
]);
產生的表格如下
(索引) | firstName | lastName | age |
0 | “Jane” | “Bond” | 未定義 |
1 | “Lars” | “Croft” | 72 |
下列表格指出在各種平台上的支援狀況
Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ||
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | |
| ✓ | ✓ |
主控台 API 包含以下用於剖析與計時的函式:
console.markTimeline(label)
[僅適用於 Safari]
console.timeStamp
相同。
console.profile(title?)
title
用於剖析報告。
console.profileEnd()
console.time(label)
label
。
console.timeEnd(label)
label
的計時器,並列印從開始計時以來經過的時間。
console.timeStamp(label?)
label
的時間戳記。可能會記錄到主控台或時間軸。
下列表格指出在各種平台上的支援狀況
Chrome | Firebug | Firefox | IE | Node.js | Safari | |
| ✓ | |||||
| ✓ | ✓ | (devtools) | ✓ | ✓ | |
| ✓ | ✓ | (devtools) | ✓ | ✓ | |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| ✓ | ✓ |
markTimeline
以斜體排版,因為它僅在單一平台上受支援。(devtools) 標示表示必須開啟開發人員工具才能讓函式運作。[19]
以下全域變數用作函式的命名空間。有關詳細資訊,請參閱括號中指出的資料:
以下全域變數包含特殊值。有關它們的詳細資訊,請檢閱 括號中指出的資料:
未定義
表示某個東西不存在的值 (undefined 和 null)
> ({}.foo) === undefined true
NaN
表示某個東西「不是數字」(NaN)
> 1 / 'abc' NaN
無限大
表示數值無限大 ∞ 的值 (Infinity)
> 1 / 0 Infinity