中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

阜陽網站開發(fā)招聘seo營銷服務

阜陽網站開發(fā)招聘,seo營銷服務,怎么在360上做推廣,wordpress 最新文章列表第二十一章:數學 原文:21. Math 譯者:飛龍 協議:CC BY-NC-SA 4.0 Math對象用作多個數學函數的命名空間。本章提供了一個概述。 數學屬性 Math的屬性如下: Math.E 歐拉常數(e) Math.LN2 2 …

第二十一章:數學

原文:21. Math

譯者:飛龍

協議:CC BY-NC-SA 4.0

Math對象用作多個數學函數的命名空間。本章提供了一個概述。

數學屬性

Math的屬性如下:

Math.E

歐拉常數(e)

Math.LN2

2 的自然對數

Math.LN10

10 的自然對數

Math.LOG2E

e 的底數 2 對數

Math.LOG10E

e 的十進制對數

Math.PI

圓的周長與直徑的比值(3.14159 …),π

Math.SQRT1_2

一半的平方根,外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

Math.SQRT2

二的平方根,外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

數值函數

Math的數值函數包括以下內容:

Math.abs(x)

返回x的絕對值。

Math.ceil(x)

返回大于等于x的最小整數:

> Math.ceil(3.999)
4
> Math.ceil(3.001)
4
> Math.ceil(-3.001)
-3
> Math.ceil(3.000)
3

有關將浮點數轉換為整數的更多信息,請參閱轉換為整數。

Math.exp(x)

返回 e^x,其中 e 是歐拉常數(Math.E)。這是Math.log()的反函數。

Math.floor(x)

返回小于等于x的最大整數:

> Math.floor(3.999)
3
> Math.floor(3.001)
3
> Math.floor(-3.001)
-4
> Math.floor(3.000)
3

有關將浮點數轉換為整數的更多信息,請參閱轉換為整數。

Math.log(x)

返回x的自然(以 e 為底)對數 ln(x)。這是Math.exp()的反函數。

Math.pow(x, y)

返回 x^y,xy次冪:

> Math.pow(9, 2)
81
> Math.pow(36, 0.5)
6

Math.round(x)

返回x四舍五入到最接近的整數(如果在兩個整數之間,則為較大的整數):

> Math.round(3.999)
4
> Math.round(3.001)
3
> Math.round(3.5)
4
> Math.round(-3.5)
-3

有關將浮點數轉換為整數的更多信息,請參閱轉換為整數。

Math.sqrt(x)

返回外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳x的平方根:

> Math.sqrt(256)
16

三角函數

三角函數方法接受弧度作為角度并返回。以下函數向您展示了如何實現轉換,如果需要的話:

  • 從度到弧度:

    function toRadians(degrees) {return degrees / 180 * Math.PI;
    }
    

以下是交互:

    > toRadians(180)3.141592653589793> toRadians(90)1.5707963267948966```+   從弧度到度:```jsfunction toDegrees(radians) {return radians / Math.PI * 180;}```以下是交互:```js> toDegrees(Math.PI * 2)360> toDegrees(Math.PI)180```三角函數方法如下:`Math.acos(x)`返回`x`的反余弦值。`Math.asin(x)`返回`x`的反正弦值。`Math.atan(x)`返回`x`的反正切值。`Math.atan2(y, x)`返回商的反正切值![](inleq_2104.png)。`Math.cos(x)`返回`x`的余弦值。`Math.sin(x)`返回`x`的正弦值。`Math.tan(x)`返回`x`的正切值。## 其他函數以下是剩余的`Math`函數:`min(x1?, x2?, ...)`返回參數中的最小數:```js
> Math.min()
Infinity
> Math.min(27)
27
> Math.min(27, -38)
-38
> Math.min(27, -38, -43)
-43

通過apply()在數組上使用它(參見func.apply(thisValue, argArray)):

> Math.min.apply(null, [27, -38, -43])
-43

max(x1?, x2?, ...)

返回參數中的最大數:

> Math.max()
-Infinity
> Math.max(7)
7
> Math.max(7, 10)
10
> Math.max(7, 10, -333)
10

通過apply()在數組上使用它(參見func.apply(thisValue, argArray)):

> Math.max.apply(null, [7, 10, -333])
10

Math.random()

/*** Compute a random integer within the given range.** @param [lower] Optional lower bound. Default: zero.* @returns A random integer i, lower ≤ i < upper*/
function getRandomInteger(lower, upper) {if (arguments.length === 1) {upper = lower;lower = 0;}return Math.floor(Math.random() * (upper - lower)) + lower;
}

第二十二章:JSON

原文:22. JSON

譯者:飛龍

協議:CC BY-NC-SA 4.0

JSON(JavaScript 對象表示)是一種用于數據存儲的純文本格式。它已經成為 Web 服務、配置文件等數據交換格式的一種流行選擇。ECMAScript 5 有一個 API,用于將 JSON 格式的字符串轉換為 JavaScript 值(解析)以及反之(字符串化)。

背景

本節(jié)解釋了 JSON 是什么以及它是如何創(chuàng)建的。

數據格式

JSON 將數據存儲為純文本。它的語法是 JavaScript 表達式語法的子集。例如:

{"first": "Jane","last": "Porter","married": true,"born": 1890,"friends": [ "Tarzan", "Cheeta" ]
}

JSON 使用 JavaScript 表達式中的以下結構:

復合

JSON 數據的對象和 JSON 數據的數組

原子

字符串、數字、布爾值和空值

它遵循以下規(guī)則:

  • 字符串必須始終用雙引號括起來;例如,像'mystr'這樣的字符串字面量是非法的。

  • 屬性鍵必須用雙引號括起來

歷史

Douglas Crockford 于 2001 年發(fā)現了 JSON。他給它起了個名字,并在json.org上發(fā)布了一個規(guī)范:

我發(fā)現了 JSON。我不主張發(fā)明 JSON,因為它已經存在于自然界中。我所做的是發(fā)現它,我給它起了名字,我描述了它的有用之處。我不主張自己是第一個發(fā)現它的人;我知道至少有其他人在我之前至少一年發(fā)現了它。我發(fā)現的最早的情況是,Netscape 有人在至少 1996 年就開始使用 JavaScript 數組文字進行數據通信,而這至少比我想到這個想法早了五年。

最初,Crockford 希望 JSON 有一個名字叫JavaScript 標記語言,但是 JSML 的首字母縮寫已經被JSpeech 標記語言使用了。

JSON 規(guī)范已經被翻譯成許多人類語言,現在有許多編程語言的庫支持解析和生成 JSON。

語法

Douglas Crockford 創(chuàng)建了一張 JSON 名片,正面有一個徽標(參見圖 22-1),背面有完整的語法(參見圖 22-2)。這使得 JSON 的簡單性在視覺上顯而易見。

JSON 名片的正面顯示了一個徽標(來源:Eric Miraglia)。圖 22-1:JSON 名片的正面顯示了一個徽標(來源:Eric Miraglia)。

JSON 名片的背面包含完整的語法(來源:Eric Miraglia)。圖 22-2:JSON 名片的背面包含完整的語法(來源:Eric Miraglia)。

語法可以轉錄如下:

object{ }{ members }memberspairpair , memberspairstring : valuearray[ ][ elements ]elementsvaluevalue , elementsvaluestringnumberobjectarraytruefalsenullstring""" chars "charscharchar charscharany-Unicode-character-except-"-or-\-or-control-character\" \\ \/ \b \f \n \r \t\u four-hex-digitsnumberintint fracint expint frac expintdigitdigit1-9 digits- digit- digit1-9 digitsfrac. digitsexpe digitsdigitsdigitdigit digitsee e+ e-E E+ E-

全局變量JSON用作生成和解析帶有 JSON 數據的字符串的函數的命名空間。

JSON.stringify(value, replacer?, space?)

JSON.stringify(value, replacer?, space?)將 JavaScript 值value轉換為 JSON 格式的字符串。它有兩個可選參數。

可選參數replacer用于在對其進行字符串化之前更改value。它可以是:

  • 一個節(jié)點訪問者(參見通過節(jié)點訪問者轉換數據)在將其字符串化之前轉換值樹。例如:

    function replacer(key, value) {if (typeof value === 'number') {value = 2 * value;}return value;
    }
    

使用 replacer:

    > JSON.stringify({ a: 5, b: [ 2, 8 ] }, replacer)'{"a":10,"b":[4,16]}'```+   隱藏所有不在列表中的屬性鍵(非數組對象的屬性)的屬性白名單。例如:```js> JSON.stringify({foo: 1, bar: {foo: 1, bar: 1}}, ['bar'])'{"bar":{"bar":1}}'```白名單對數組沒有影響:```js> JSON.stringify(['a', 'b'], ['0'])'["a","b"]'```可選參數`space`影響輸出的格式。如果沒有這個參數,`stringify`的結果將是單行文本:```js
> console.log(JSON.stringify({a: 0, b: ['\n']}))
{"a":0,"b":["\n"]}

使用它,可以插入換行符,并且通過數組和對象的每個嵌套級別增加縮進。有兩種指定縮進方式的方法:

一個數字

將數字乘以縮進級別并將行縮進為相同數量的空格。小于 0 的數字被解釋為 0;大于 10 的數字被解釋為 10:

> console.log(JSON.stringify({a: 0, b: ['\n']}, null, 2))
{"a": 0,"b": ["\n"]
}

一個字符串

要縮進,重復給定的字符串以表示每個縮進級別。只使用字符串的前 10 個字符:

> console.log(JSON.stringify({a: 0, b: ['\n']}, null, '|--'))
{
|--"a": 0,
|--"b": [
|--|--"\n"
|--]
}

因此,以下對JSON.stringify()的調用會將對象打印為一個格式良好的樹:

JSON.stringify(data, null, 4)

JSON.stringify()忽略的數據

在對象中,JSON.stringify()只考慮可枚舉的自有屬性(參見屬性特性和屬性描述符)。以下示例演示了忽略了不可枚舉的自有屬性obj.foo

> var obj = Object.defineProperty({}, 'foo', { enumerable: false, value: 7 });
> Object.getOwnPropertyNames(obj)
[ 'foo' ]
> obj.foo
7
> JSON.stringify(obj)
'{}'

JSON.stringify()處理不受 JSON 支持的值(例如函數和undefined)的方式取決于它們遇到的位置。不支持的值本身導致stringify()返回undefined而不是字符串:

> JSON.stringify(function () {})
undefined

其值不受支持的屬性將被簡單地忽略:

> JSON.stringify({ foo: function () {} })
'{}'

數組中不支持的值將被字符串化為null

> JSON.stringify([ function () {} ])
'[null]'

toJSON()方法

如果JSON.stringify()遇到具有toJSON方法的對象,則使用該方法獲取要字符串化的值。例如:

> JSON.stringify({ toJSON: function () { return 'Cool' } })
'"Cool"'

日期已經有一個產生 ISO 8601 日期字符串的toJSON方法:

> JSON.stringify(new Date('2011-07-29'))
'"2011-07-28T22:00:00.000Z"'

toJSON方法的完整簽名如下:

function (key)

key參數允許您根據上下文以不同方式進行字符串化。它始終是一個字符串,并指示在父對象中找到您的對象的位置:

根位置

空字符串

屬性值

屬性鍵

數組元素

元素的索引作為字符串

我將通過以下對象演示toJSON()

var obj = {toJSON: function (key) {// Use JSON.stringify for nicer-looking outputconsole.log(JSON.stringify(key));return 0;}
};

如果使用JSON.stringify(),則每次出現obj都會被替換為0。通知toJSON()方法在屬性鍵'foo'和數組索引 0 處遇到了obj

> JSON.stringify({ foo: obj, bar: [ obj ]})
"foo"
"0"
'{"foo":0,"bar":[0]}'

內置的toJSON()方法如下:

  • Boolean.prototype.toJSON()

  • Number.prototype.toJSON()

  • String.prototype.toJSON()

  • Date.prototype.toJSON()

JSON.parse(text, reviver?)

JSON.parse(text, reviver?)解析text中的 JSON 數據并返回 JavaScript 值。以下是一些示例:

> JSON.parse("'String'") // illegal quotes
SyntaxError: Unexpected token ILLEGAL
> JSON.parse('"String"')
'String'
> JSON.parse('123')
123
> JSON.parse('[1, 2, 3]')
[ 1, 2, 3 ]
> JSON.parse('{ "hello": 123, "world": 456 }')
{ hello: 123, world: 456 }

可選參數reviver是一個節(jié)點訪問者(參見通過節(jié)點訪問者轉換數據),可用于轉換解析后的數據。在此示例中,我們將日期字符串轉換為日期對象:

function dateReviver(key, value) {if (typeof value === 'string') {var x = Date.parse(value);if (!isNaN(x)) { // valid date string?return new Date(x);}}return value;
}

以下是交互:

> var str = '{ "name": "John", "birth": "2011-07-28T22:00:00.000Z" }';
> JSON.parse(str, dateReviver)
{ name: 'John', birth: Thu, 28 Jul 2011 22:00:00 GMT }

通過節(jié)點訪問者轉換數據

JSON.stringify()JSON.parse()都允許您通過傳遞函數來轉換 JavaScript 數據:

  • JSON.stringify()允許您在將其轉換為 JSON 之前更改 JavaScript 數據。

  • JSON.parse()解析 JSON,然后讓您對生成的 JavaScript 數據進行后處理。

JavaScript 數據是一個樹,其復合節(jié)點是數組和對象,其葉子是原始值(布爾值,數字,字符串,null)。讓我們將傳遞的轉換函數稱為節(jié)點訪問者。這些方法遍歷樹并為每個節(jié)點調用訪問者。然后可以選擇替換或刪除節(jié)點。節(jié)點訪問者的簽名如下:

function nodeVisitor(key, value)

參數是:

this

當前節(jié)點的父節(jié)點。

key

當前節(jié)點位于其父節(jié)點內的鍵。key 總是一個字符串。

當前節(jié)點。

根節(jié)點 root 沒有父節(jié)點。當訪問 root 時,為其創(chuàng)建了一個偽父節(jié)點,并且參數具有以下值:

  • this{ '': root }。

  • key''。

  • valueroot。

節(jié)點訪問者有三種返回值的選項:

  • 返回 value,然后不執(zhí)行任何更改。

  • 返回不同的值。然后當前節(jié)點被替換。

  • 返回 undefined。然后移除節(jié)點。

以下是節(jié)點訪問者的示例。它記錄了傳遞給它的值。

function nodeVisitor(key, value) {console.log([// Use JSON.stringify for nicer-looking outputJSON.stringify(this), // parentJSON.stringify(key),JSON.stringify(value)].join(' # '));return value; // don't change node
}

讓我們使用此函數來檢查 JSON 方法如何迭代 JavaScript 數據。

JSON.stringify()

特殊的根節(jié)點首先出現在前綴迭代中(父節(jié)點在子節(jié)點之前)。訪問的第一個節(jié)點始終是偽根。在每次調用后顯示的最后一行是 stringify() 返回的字符串:

> JSON.stringify(['a','b'], nodeVisitor)
{"":["a","b"]} # "" # ["a","b"]
["a","b"] # "0" # "a"
["a","b"] # "1" # "b"
'["a","b"]'> JSON.stringify({a:1, b:2}, nodeVisitor)
{"":{"a":1,"b":2}} # "" # {"a":1,"b":2}
{"a":1,"b":2} # "a" # 1
{"a":1,"b":2} # "b" # 2
'{"a":1,"b":2}'> JSON.stringify('abc', nodeVisitor)
{"":"abc"} # "" # "abc"
'"abc"'

JSON.parse()

首先是葉子節(jié)點,在后綴迭代中(子節(jié)點在父節(jié)點之前)。訪問的最后一個節(jié)點始終是偽根。在每次調用后顯示的最后一行是 parse() 返回的 JavaScript 值:

> JSON.parse('["a","b"]', nodeVisitor)
["a","b"] # "0" # "a"
["a","b"] # "1" # "b"
{"":["a","b"]} # "" # ["a","b"]
[ 'a', 'b' ]> JSON.parse('{"a":1, "b":2}', nodeVisitor)
{"a":1,"b":2} # "a" # 1
{"a":1,"b":2} # "b" # 2
{"":{"a":1,"b":2}} # "" # {"a":1,"b":2}
{ a: 1, b: 2 }> JSON.parse('"hello"', nodeVisitor)
{"":"hello"} # "" # "hello"
'hello'

第二十三章:標準全局變量

原文:23. Standard Global Variables

譯者:飛龍

協議:CC BY-NC-SA 4.0

本章是 ECMAScript 規(guī)范標準化的全局變量的參考。Web 瀏覽器有更多全局變量,這些變量在 MDN 上列出。所有全局變量都是全局對象的(自有或繼承的)屬性(在瀏覽器中是 window;參見 全局對象)。

構造函數

有關以下構造函數的詳細信息,請參見括號中指示的部分:

  • Array([數組構造函數](ch18.html#array_constructor “數組構造函數”))

  • Boolean([原始值的包裝對象](ch08.html#wrapper_objects “原始值的包裝對象”))

  • Date([日期構造函數](ch20.html#date_constructors “日期構造函數”))

  • Function([使用 new Function() 評估代碼](ch23.html#function_constructor “使用 new Function() 評估代碼”))

  • Number([原始值的包裝對象](ch08.html#wrapper_objects “原始值的包裝對象”))

  • 對象([將任何值轉換為對象](ch17_split_000.html#toobject “將任何值轉換為對象”))

  • RegExp([創(chuàng)建正則表達式](ch19.html#creating_regexps “創(chuàng)建正則表達式”))

  • String([原始值的包裝對象](ch08.html#wrapper_objects “原始值的包裝對象”))

錯誤構造函數

有關這些構造函數的詳細信息,請參見 [錯誤構造函數](ch14.html#error_constructors “錯誤構造函數”):

  • Error

  • EvalError

  • RangeError

  • ReferenceError

  • SyntaxError

  • TypeError

  • URIError

非構造函數

有幾個全局函數不是構造函數。它們在本節(jié)中列出。

編碼和解碼文本

以下函數處理 URI 編碼和解碼的幾種方式:

encodeURI(uri)

uri 中對特殊字符進行百分比編碼。特殊字符是除以下字符外的所有 Unicode 字符:

URI 字符:; , / ? : @ & = + $ #
未編碼:a-z A-Z 0-9 - _ . ! ~ * ' ( )

例如:

> encodeURI('http://example.com/Für Elise/')
'http://example.com/F%C3%BCr%20Elise/'

encodeURIComponent(uriComponent)

uriComponent 中對所有字符進行百分比編碼,除了:

| 未編碼: | a-z A-Z 0-9 - _ . ! ~ * ' ( ) |

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 也不會對其進行解碼,即使它們已經被正確編碼:

> 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()和 new Function()動態(tài)評估 JavaScript 代碼

本節(jié)將介紹如何在 JavaScript 中動態(tài)評估代碼。

使用 eval()評估代碼

函數調用:

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()

對于eval(),您確實應該使用嚴格模式(參見嚴格模式)。在松散模式下,評估的代碼可以在周圍范圍內創(chuàng)建局部變量:

function sloppyFunc() {eval('var foo = 123');  // added to the scope of sloppyFuncconsole.log(foo);  // 123
}

在嚴格模式下無法發(fā)生:

function strictFunc() {'use strict';eval('var foo = 123');console.log(foo);  // ReferenceError: foo is not defined
}

然而,即使在嚴格模式下,評估的代碼仍然可以讀取和寫入周圍范圍內的變量。要防止這種訪問,您需要間接調用eval()

間接 eval()在全局范圍內進行評估

有兩種調用eval()的方法:

  • 直接。通過直接調用名稱為“eval”的函數。

  • 間接調用。以其他方式(通過call(),作為window的方法,通過在不同名稱下存儲它并在那里調用等)。

正如我們已經看到的,直接eval()在當前范圍內執(zhí)行代碼:

var x = 'global';function directEval() {'use strict';var x = 'local';console.log(eval('x')); // local
}

相反,間接eval()在全局范圍內執(zhí)行它:

var x = 'global';function indirectEval() {'use strict';var x = 'local';// Don’t call eval directlyconsole.log(eval.call(null, 'x')); // globalconsole.log(window.eval('x')); // globalconsole.log((1, eval)('x')); // global (1)// Change the name of evalvar xeval = eval;console.log(xeval('x')); // global// Turn eval into a methodvar obj = { eval: eval };console.log(obj.eval('x')); // global
}

(1)的解釋:當您通過名稱引用變量時,初始結果是所謂的引用,一個具有兩個主要字段的數據結構:

  • base指向環(huán)境,即變量值存儲的數據結構。

  • referencedName是變量的名稱。

eval()函數調用期間,函數調用運算符(括號)遇到對eval的引用,并且可以確定要調用的函數的名稱。因此,這樣的函數調用觸發(fā)了直接的eval()。但是,您可以通過不給出調用運算符的引用來強制間接eval()。這是通過在應用運算符之前檢索引用的值來實現的。逗號運算符在第(1)行為我們執(zhí)行此操作。此運算符評估第一個操作數并返回評估第二個操作數的結果。評估始終產生值,這意味著引用被解析并丟失了函數名稱。

間接評估的代碼總是松散的。這是代碼獨立于其當前環(huán)境進行評估的結果:

function strictFunc() {'use strict';var code = '(function () { return this }())';var result = eval.call(null, code);console.log(result !== undefined); // true, sloppy mode
}

使用 new Function()評估代碼

構造函數Function()的簽名為:

new Function(param1, ..., paramN, funcBody)

它創(chuàng)建一個函數,其零個或多個參數的名稱為param1parem2等,其主體為funcBody;也就是說,創(chuàng)建的函數如下所示:

function (?param1?, ..., ?paramN?) {?funcBody?
}

讓我們使用new Function()創(chuàng)建一個函數f,它返回其參數的總和:

> var f = new Function('x', 'y', 'return x+y');
> f(3, 4)
7

類似于間接eval()new Function()創(chuàng)建其作用域為全局的函數:1?

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 modevar st = new Function('"use strict"; return this');console.log(st() === undefined); // true, strict mode
}

eval()與 new Function()

通常,最好使用new Function()而不是eval()來評估代碼:函數參數為評估的代碼提供了清晰的接口,而且你不需要間接eval()的略顯笨拙的語法來確保評估的代碼只能訪問全局變量(除了它自己的變量)。

最佳實踐

你不應該使用eval()new Function()。動態(tài)評估代碼很慢,而且存在潛在的安全風險。它還會阻止大多數使用靜態(tài)分析的工具(如 IDE)考慮代碼。

通常有更好的替代方案。例如,Brendan Eich 最近在推特上發(fā)推文指出了程序員們使用的反模式,他們想要訪問存儲在變量propName中的屬性:

var value = eval('obj.'+propName);

這個想法是有道理的:點運算符只支持固定的,靜態(tài)提供的屬性鍵。在這種情況下,屬性鍵只在運行時知道,這就是為什么需要eval()來使用該運算符。幸運的是,JavaScript 還有方括號運算符,它接受動態(tài)屬性鍵。因此,以下是前面代碼的更好版本:

var value = obj[propName];

你也不應該使用eval()new Function()來解析 JSON 數據。這是不安全的。要么依賴 ECMAScript 5 對 JSON 的內置支持(參見第二十二章),要么使用一個庫。

合法的用例

eval()new Function()有一些合法的,盡管是高級的用例:帶有函數的配置數據(JSON 不允許),模板庫,解釋器,命令行和模塊系統(tǒng)。

結論

這是 JavaScript 動態(tài)評估代碼的一個相對高級的概述。如果你想深入了解,可以查看 kangax 的文章“全局 eval。有哪些選項?”。

控制臺 API

在大多數 JavaScript 引擎中,有一個全局對象console,其中包含用于記錄和調試的方法。該對象不是語言本身的一部分,但已成為事實上的標準。由于它們的主要目的是調試,console方法在開發(fā)過程中最常用,而在部署的代碼中很少使用。

本節(jié)概述了控制臺 API。它記錄了 Chrome 32、Firebug 1.12、Firefox 25、Internet Explorer 11、Node.js 0.10.22 和 Safari 7.0 的現狀。

控制臺 API 在各種引擎之間的標準化程度如何?

控制臺 API 的實現差異很大,而且不斷變化。如果你想要權威的文檔,你有兩個選擇。首先,你可以查看 API 的標準概述:

  • Firebug 首先實現了控制臺 API,其在其維基中的文檔是目前最接近標準的東西。

  • 此外,Brian Kardell 和 Paul Irish 正在制定API 規(guī)范,這應該會導致更一致的行為。

其次,你可以查看各種引擎的文檔:

  • Chrome

  • Firebug

  • Firefox

  • Internet Explorer

  • Node.js

  • Safari

警告

在 Internet Explorer 9 中存在一個錯誤。在該瀏覽器中,只有開發(fā)者工具至少打開過一次,console對象才存在。這意味著如果在工具打開之前引用console,你會得到一個ReferenceError。作為一種解決方法,你可以檢查console是否存在,如果不存在則創(chuàng)建一個虛擬實現。

簡單的日志記錄

控制臺 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?, ...)

將參數記錄到控制臺。在瀏覽器中,記錄的內容可能會被“警告”圖標標記,和/或包括堆棧跟蹤或代碼鏈接。

在以下表中指出了各種平臺的支持:

ChromeFirebugFirefoxIENode.jsSafari
clear????
debug?????
error??????
exception?
info??????
log??????
trace??????
warn??????

exception以斜體排版,因為它只在單個平臺上受支持。

檢查和計數

控制臺 API 包括以下檢查和計數方法:

console.assert(expr, obj?)

如果exprfalse,則將obj記錄到控制臺并拋出異常。如果為true,則什么也不做。

console.count(label?)

計算帶有此語句的行被執(zhí)行的次數。

在以下表中指出了各種平臺的支持:

ChromeFirebugFirefoxIENode.jsSafari
assert?????
count????

格式化日志

控制臺 API 包括以下格式化日志的方法:

console.dir(object)

將對象的表示打印到控制臺。在瀏覽器中,該表示可以交互地進行探索。

console.dirxml(object)

打印 HTML 或 XML 元素的 XML 源樹。

console.group(object1?, object2?, ...)

將對象記錄到控制臺并打開一個包含所有未來記錄內容的嵌套塊。通過調用console.groupEnd()來關閉該塊。該塊最初是展開的,但可以折疊。

console.groupCollapsed(object1?, object2?, ...)

類似于console.group(),但是該塊最初是折疊的。

console.groupEnd()

關閉由console.group()console.groupCollapsed()打開的組。

console.table(data, columns?)

將數組打印為表格,每行一個元素??蛇x參數columns指定在列中顯示哪些屬性/數組索引。如果缺少該參數,則所有屬性鍵都將用作表格列。缺少的屬性和數組元素顯示為列中的undefined

var persons = [{ firstName: 'Jane', lastName: 'Bond' },{ firstName: 'Lars', lastName: 'Croft', age: 72 }
];
// Equivalent:
console.table(persons);
console.table(persons, ['firstName', 'lastName', 'age']);

結果表如下:

(索引)名字姓氏年齡
0“Jane”“Bond”undefined
1“Lars”“Croft”72

在以下表中指出了各種平臺的支持:

ChromeFirebugFirefoxIENode.jsSafari
dir??????
dirxml????
group?????
groupCollapsed?????
groupEnd?????
table??

分析和計時

控制臺 API 包括以下用于分析和計時的方法:

控制臺.標記時間線(標簽) [僅限 Safari]

console.timeStamp相同。

控制臺.性能(標題?)

打開分析。可選的title用于分析報告。

控制臺.分析結束()

停止分析并打印分析報告。

控制臺.時間(標簽)

啟動標簽為label的計時器。

控制臺.時間結束(標簽)

停止標簽為label的計時器并打印自啟動以來經過的時間。

控制臺.時間戳(標簽?)

記錄具有給定label的時間戳??梢杂涗浀娇刂婆_或時間軸。

以下表格顯示了各種平臺上的支持:

ChromeFirebugFirefoxIENode.jsSafari
markTimeline?
profile??(devtools)??
profileEnd??(devtools)??
time??????
timeEnd??????
timeStamp??

markTimeline以斜體排版,因為它僅在單個平臺上受支持。 (devtools)表示必須打開開發(fā)人員工具才能使該方法起作用。1?

命名空間和特殊值

以下全局變量用作函數的命名空間。有關詳細信息,請參閱括號中指示的材料:

JSON

JSON API 功能([第二十二章](ch22.html “第二十二章.JSON”))

數學

數學 API 功能([第二十一章](ch21.html “第二十一章.數學”))

對象

元編程功能([對象操作小抄:使用對象](ch17_split_001.html#oop_cheat_sheet “對象操作小抄:使用對象”))

以下全局變量包含特殊值。有關更多信息,請查看括號中指示的材料:

未定義

表示某物不存在的值([未定義和 null](ch08.html#undefined_null “未定義和 null”):

> ({}.foo) === undefined
true

NaN

一個表示某物是“非數字”([NaN](ch11.html#nan “NaN”)的值:

> 1 / 'abc'
NaN

無窮大

表示數值無窮大∞的值([無窮大](ch11.html#infinity “無窮大”):

> 1 / 0
Infinity

1? Mariusz Nowak(@medikoo)告訴我,由Function評估的代碼默認情況下在任何地方都是松散的。

1? 感謝 Matthias Reuter(@gweax)和 Philipp Kyeck(@pkyeck)對本節(jié)的貢獻。

第二十四章: Unicode 和 JavaScript

原文:24. Unicode and JavaScript

譯者:飛龍

協議:CC BY-NC-SA 4.0

本章是對 Unicode 及其在 JavaScript 中的處理的簡要介紹。

Unicode 歷史

Unicode 始于 1987 年,由 Joe Becker(施樂),Lee Collins(蘋果)和 Mark Davis(蘋果)發(fā)起。其想法是創(chuàng)建一個通用字符集,因為當時對于編碼純文本存在許多不兼容的標準:許多變體的 8 位 ASCII,Big Five(繁體中文),GB 2312(簡體中文)等。在 Unicode 之前,沒有多語言純文本的標準,但有豐富的文本系統(tǒng)(例如蘋果的 WorldScript),允許您組合多個編碼。

第一份 Unicode 草案提案于 1988 年發(fā)布。此后繼續(xù)工作并擴大工作組。Unicode 聯盟于 1991 年 1 月 3 日成立:

Unicode 聯盟是一家致力于開發(fā)、維護和推廣軟件國際化標準和數據的非營利性公司,特別是 Unicode 標準[…]

Unicode 1.0 標準的第一卷于 1991 年 10 月出版,第二卷于 1992 年 6 月出版。

重要的 Unicode 概念

字符的概念可能看起來很簡單,但它有許多方面。這就是為什么 Unicode 是一個如此復雜的標準。以下是重要的基本概念:

字符和字形

這兩個術語的意思相似。字符是數字實體,而字形是書面語言的原子單位(字母、印刷連字、中文字符、標點符號等)。程序員以字符為思考單位,而用戶以字形為思考單位。有時需要使用多個字符來表示單個字形。例如,我們可以通過組合字符o和字符^(抑揚符)來產生單個字形?。

字形

這是一種顯示字形的具體方式。有時,相同的字形在不同的上下文或其他因素下顯示方式不同。例如,字形fi可以呈現為字形f和字形i,通過連字字形連接,或者沒有連字。

代碼點

Unicode 通過稱為代碼點的數字來表示它支持的字符。代碼點的十六進制范圍是 0x0 到 0x10FFFF(17 倍 16 位)。

代碼單元

為了存儲或傳輸代碼點,我們將它們編碼為代碼單元,這是具有固定長度的數據片段。長度以位為單位,并由編碼方案確定,Unicode 有幾種編碼方案,例如 UTF-8 和 UTF-16。名稱中的數字表示代碼單元的長度,以位為單位。如果一個代碼點太大而無法適應單個代碼單元,它必須被分解為多個單元;也就是說,表示單個代碼點所需的代碼單元數量可能會有所不同。

BOM(字節(jié)順序標記)

如果一個代碼單元大于一個字節(jié),字節(jié)順序很重要。BOM 是文本開頭的一個偽字符(可能被編碼為多個代碼單元),指示代碼單元是大端(最重要的字節(jié)在前)還是小端(最不重要的字節(jié)在前)。沒有 BOM 的文本的默認值是大端。BOM 還指示所使用的編碼;對于 UTF-8、UTF-16 等編碼是不同的。此外,如果 Web 瀏覽器沒有關于文本編碼的其他信息,它還可以作為 Unicode 的標記。然而,由于幾個原因,BOM 并不經常使用:

  • UTF-8 是迄今為止最流行的 Unicode 編碼,不需要 BOM,因為只有一種字節(jié)排序方式。

  • 幾種字符編碼規(guī)定了固定的字節(jié)順序。那么就不應該使用 BOM。例如 UTF-16BE(UTF-16 大端)、UTF-16LE、UTF-32BE 和 UTF-32LE。這是處理字節(jié)順序的更安全的方式,因為元數據和數據保持分開,不會混淆。

規(guī)范化

有時相同的字形可以用幾種方式表示。例如,字形?可以表示為單個代碼點,也可以表示為一個o后跟一個組合字符¨(分音符,雙點)。規(guī)范化是將文本轉換為規(guī)范表示的過程;等效的代碼點和代碼點序列都被轉換為相同的代碼點(或代碼點序列)。這對于文本處理(例如搜索文本)很有用。Unicode 規(guī)定了幾種規(guī)范化。

字符屬性

規(guī)范指定了規(guī)范的幾個屬性,其中一些列在這里:

  • 名稱。一個由大寫字母 A-Z,數字 0-9,連字符(-)和<空格>組成的英文名稱。兩個例子:

  • “λ”的名稱是“希臘小寫字母λ”。

  • “!”的名稱是“感嘆號”。

  • 一般類別。將字符分成字母、大寫字母、數字和標點等類別。

  • 年齡。該字符是在哪個版本的 Unicode 中引入的(1.0、1.1、2.0 等)?

  • 已棄用。是否不鼓勵使用該字符?

  • 以及更多。

代碼點

代碼點的范圍最初是 16 位。隨著 Unicode 版本 2.0(1996 年 7 月)的擴展,它現在被分成了 17 個平面,編號從 0 到 16。每個平面包括 16 位(十六進制表示法:0x0000–0xFFFF)。因此,在接下來的十六進制范圍中,四個底部以外的數字包含了平面的編號。

  • 第 0 平面,基本多文種平面(BMP):0x0000–0xFFFF

  • 第 1 平面,補充多語種平面(SMP):0x10000–0x1FFFF

  • 第 2 平面,補充表意文字平面(SIP):0x20000–0x2FFFF

  • 第 3–13 平面,未分配

  • 第 14 平面,補充特殊用途平面(SSP):0xE0000–0xEFFFF

  • 第 15–16 平面,補充專用區(qū)域(S PUA A/B):0x0F0000–0x10FFFF

第 1–16 平面稱為補充平面星際平面

Unicode 編碼

UTF-32(Unicode 轉換格式 32)是一種具有 32 位代碼單元的格式。任何代碼點都可以由單個代碼單元編碼,使得這是唯一的固定長度編碼;對于其他編碼,編碼一個點所需的單元數量是變化的。

UTF-16是一種具有 16 位代碼單元的格式,需要一個到兩個單元來表示一個代碼點。BMP 代碼點可以由單個代碼單元表示。高代碼點是 20 位(16 乘以 16 位),在減去 0x10000(BMP 的范圍)后。這些位被編碼為兩個代碼單元(所謂的代理對):

領先代理

最重要的 10 位:存儲在范圍 0xD800–0xDBFF 中。也稱為高代理代碼單元。

尾隨代理

最不重要的 10 位:存儲在范圍 0xDC00–0xDFFF 中。也稱為低代理代碼單元。

以下表格(改編自 Unicode 標準 6.2.0,表 3-5)可視化了位的分布:

代碼點UTF-16 代碼單元
xxxxxxxxxxxxxxxx(16 位)xxxxxxxxxxxxxxxx
pppppxxxxxxyyyyyyyyyy(21 位=5+6+10 位)110110qqqqxxxxxx 110111yyyyyyyyyy(qqqq = ppppp ? 1)

為了啟用這種編碼方案,BMP 有一個未使用的代碼點范圍為 0xD800–0xDFFF 的空隙。因此,領先代理、尾隨代理和 BMP 代碼點的范圍是不相交的,使得在面對錯誤時解碼更加健壯。以下函數將代碼點編碼為 UTF-16(稍后我們將看到一個使用它的示例):

function toUTF16(codePoint) {var TEN_BITS = parseInt('1111111111', 2);function u(codeUnit) {return '\\u'+codeUnit.toString(16).toUpperCase();}if (codePoint <= 0xFFFF) {return u(codePoint);}codePoint -= 0x10000;// Shift right to get to most significant 10 bitsvar leadingSurrogate = 0xD800 | (codePoint >> 10);// Mask to get least significant 10 bitsvar trailingSurrogate = 0xDC00 | (codePoint & TEN_BITS);return u(leadingSurrogate) + u(trailingSurrogate);
}

UCS-2,一種已棄用的格式,使用 16 位代碼單元來表示(僅!)BMP 的代碼點。當 Unicode 代碼點的范圍擴展到 16 位之外時,UTF-16 取代了 UCS-2。

UTF-8具有 8 位代碼單元。它在傳統(tǒng) ASCII 編碼和 Unicode 之間架起了一座橋梁。ASCII 只有 128 個字符,其編號與前 128 個 Unicode 代碼點相同。UTF-8 是向后兼容的,因為所有 ASCII 代碼都是有效的代碼單元。換句話說,在范圍 0–127 的單個代碼單元中編碼了相同范圍內的單個代碼點。這些代碼單元的最高位為零。另一方面,如果最高位為 1,則會跟隨更多的單元,以為更高的代碼點提供額外的位。這導致了以下編碼方案:

  • 0000–007F:0xxxxxxx(7 位,存儲在 1 字節(jié)中)

  • 0080–07FF:110xxxxx,10xxxxxx(5+6 位=11 位,存儲在 2 字節(jié)中)

  • 0800–FFFF:1110xxxx,10xxxxxx,10xxxxxx(4+6+6 位=16 位,存儲在 3 字節(jié)中)

  • 10000–1FFFFF:11110xxx,10xxxxxx,10xxxxxx,10xxxxxx(3+6+6+6 位=21 位,存儲在 4 字節(jié)中)。最高代碼點是 10FFFF,因此 UTF-8 有一些額外的空間。

如果最高位不為 0,則零之前的 1 的數量表示序列中有多少個代碼單元。初始單元之后的所有單元都具有位前綴 10。因此,初始代碼單元和后續(xù)代碼單元的范圍是不相交的,這有助于從編碼錯誤中恢復。

UTF-8 已成為最流行的 Unicode 格式。最初,它之所以受歡迎,是因為它與 ASCII 的向后兼容性。后來,它因其在操作系統(tǒng)、編程環(huán)境和應用程序中的廣泛和一致的支持而受到青睞。

JavaScript 源代碼和 Unicode

JavaScript 處理 Unicode 源代碼有兩種方式:內部(在解析期間)和外部(在加載文件時)。

內部源代碼

在內部,JavaScript 源代碼被視為一系列 UTF-16 代碼單元。根據第 6 節(jié)的 EMCAScript 規(guī)范:

ECMAScript 源文本以 Unicode 字符編碼的形式表示,版本為 3.0 或更高。[…] ECMAScript 源文本被假定為本規(guī)范的目的是一系列 16 位代碼單元。[…] 如果實際源文本以除 16 位代碼單元以外的形式編碼,必須處理為首先轉換為 UTF-16。

在標識符、字符串文字和正則表達式文字中,任何代碼單元也可以通過 Unicode 轉義序列\uHHHH來表示,其中HHHH是四個十六進制數字。例如:

> var f\u006F\u006F = 'abc';
> foo
'abc'> var λ = 123;
> \u03BB
123

這意味著您可以在源代碼中使用 Unicode 字符的文字和變量名,而不會離開 ASCII 范圍。

在字符串文字中,還有一種額外的轉義可用:用兩位十六進制數字表示的十六進制轉義序列,表示范圍在 0x00-0xFF 的代碼單元。例如:

> '\xF6' === '?'
true
> '\xF6' === '\u00F6'
true

外部源代碼

雖然內部使用 UTF-16,但 JavaScript 源代碼通常不以該格式存儲。當 Web 瀏覽器通過<script>標簽加載源文件時,它會確定編碼如下:

  • 如果文件以 BOM 開頭,則編碼是 UTF 變體,取決于使用的 BOM。

  • 否則,如果文件是通過 HTTP(S)加載的,那么Content-Type頭可以通過charset參數指定編碼。例如:

    Content-Type: application/javascript; charset=utf-8
    

提示

JavaScript 文件的正確媒體類型(以前稱為MIME 類型)是application/javascript。但是,較舊的瀏覽器(例如 Internet Explorer 8 及更早版本)最可靠地使用text/javascript。不幸的是,<script>標簽的type屬性的默認值是text/javascript。至少對于 JavaScript,您可以省略該屬性;包含它沒有好處。

  • 否則,如果<script>標簽具有charset屬性,則將使用該編碼。即使屬性type包含有效的媒體類型,該類型也不得具有參數charset(就像前述的Content-Type頭)。這確保了charsettype的值不會沖突。

  • 否則,使用包含<script>標簽的文檔的編碼。例如,這是 HTML5 文檔的開頭,其中<meta>標簽聲明文檔編碼為 UTF-8:

    <!doctype html>
    <html>
    <head><meta charset="UTF-8">
    ...
    

強烈建議您始終指定編碼。如果不指定,將使用特定于區(qū)域設置的默認編碼。換句話說,在不同國家,人們將以不同方式看待文件。只有最低的 7 位在各個區(qū)域設置中相對穩(wěn)定。

我的建議可以總結如下:

  • 對于您自己的應用程序,您可以使用 Unicode。但必須將應用程序的 HTML 頁面的編碼指定為 UTF-8。

  • 對于庫,最安全的做法是發(fā)布 ASCII(7 位)代碼。

一些縮小工具可以將具有超出 7 位的 Unicode 代碼點的源代碼轉換為“7 位干凈”的源代碼。它們通過用 Unicode 轉義替換非 ASCII 字符來實現。例如,以下調用UglifyJS將文件test.js翻譯為:

uglifyjs -b beautify=false,ascii-only=true test.js

文件test.js如下所示:

var σ = 'K?ln';

UglifyJS 的輸出如下:

var \u03c3="K\xf6ln";

考慮以下負面示例。有一段時間,庫 D3.js 以 UTF-8 發(fā)布。這導致了一個錯誤,因為當它從編碼不是 UTF-8 的頁面加載時,代碼包含了諸如以下語句:

var π = Math.PI, ε = 1e-6;

標識符π和ε沒有被正確解碼,也沒有被識別為有效的變量名。此外,一些超出 7 位的代碼點的字符串文字也沒有被正確解碼。作為一種解決方法,您可以通過向<script>標簽添加適當的charset屬性來加載代碼:

<script charset="utf-8" src="d3.js"></script>

JavaScript 字符串和 Unicode

JavaScript 字符串是一系列 UTF-16 代碼單元。根據 ECMAScript 規(guī)范,第 8.4 節(jié):

當一個字符串包含實際文本數據時,每個元素被認為是單個 UTF-16 代碼單元。

轉義序列

如前所述,您可以在字符串文字中使用 Unicode 轉義序列和十六進制轉義序列。例如,您可以通過將o與重音符(代碼點 0x0308)組合來產生字符?:

> console.log('o\u0308')
?

這適用于 JavaScript 命令行,例如 Web 瀏覽器控制臺和 Node.js REPL。您還可以將這種類型的字符串插入到 Web 頁面的 DOM 中。

通過轉義引用星際飛機字符

網絡上有許多不錯的 Unicode 符號表。看看 Tim Whitlock 的“Emoji Unicode Tables”,并對現代 Unicode 字體中有多少符號感到驚訝。表中的符號都不是圖像;它們都是字體字形。假設您想通過 JavaScript 顯示一個星際飛機中的 Unicode 字符(顯然,這樣做存在風險:并非所有字體都支持所有這些字符)。例如,考慮一頭奶牛,代碼點為 0x1F404:!。

您可以復制字符并直接粘貼到您的 Unicode 編碼 JavaScript 源代碼中:

JavaScript 引擎將解碼源代碼(通常為 UTF-8)并創(chuàng)建一個具有兩個 UTF-16 代碼單元的字符串?;蛘?#xff0c;您可以自己計算兩個代碼單元并使用 Unicode 轉義序列。有一些網絡應用程序可以執(zhí)行這種計算,例如:

  • UTF 轉換器

  • Mathias Bynens 的“JavaScript 轉義”

先前定義的函數toUTF16也執(zhí)行了它:

> toUTF16(0x1F404)
'\\uD83D\\uDC04'

UTF-16 代理對(0xD83D,0xDC04)確實編碼了奶牛:

計數字符

如果字符串包含代理對(兩個編碼單元編碼一個代碼點),那么length屬性不再計算圖形元素。它計算編碼單元:

這可以通過庫來修復,例如 Mathias Bynens 的Punycode.js,它與 Node.js 捆綁在一起:

> var puny = require('punycode');
> puny.ucs2.decode(str).length
1

Unicode 規(guī)范化

如果您想在字符串中搜索或比較它們,那么您需要進行規(guī)范化,例如通過庫unorm(由 Bjarke Walling)。

JavaScript 正則表達式和 Unicode

JavaScript 正則表達式中的 Unicode 支持(請參閱第十九章)非常有限。例如,沒有辦法匹配“大寫字母”等 Unicode 類別。

行終止符影響匹配。行終止符是下表中指定的四個字符之一:

代碼單元名稱字符轉義序列
\u000A換行符\n
\u000D回車\r
\u2028行分隔符
\u2029段落分隔符

以下正則表達式構造基于 Unicode:

  • \s \S(空白,非空白)具有基于 Unicode 的定義:

    > /^\s$/.test('\uFEFF')
    true
    
  • .(點)匹配所有代碼單元(不是代碼點!)除了行終止符。請參閱下一節(jié),了解如何匹配任何代碼點。

  • 多行模式/m:在多行模式下,斷言^匹配輸入的開頭和行終止符之后。斷言$匹配行終止符之前和輸入的結尾。在非多行模式下,它們只在輸入的開頭或結尾匹配。

其他重要的字符類是基于 ASCII 而不是 Unicode 定義的:

  • \d \D(數字,非數字):數字等同于[0-9]。

  • \w \W(單詞字符,非單詞字符):單詞字符等同于[A-Za-z0-9_]。

  • \b \B(在單詞邊界,單詞內):單詞是由單詞字符([A-Za-z0-9_])組成的序列。例如,在字符串'über'中,字符類轉義\b將字符b視為單詞的開始:

    > /\bb/.test('über')
    true
    

匹配任何代碼單元和任何代碼點

要匹配任何代碼單元,您可以使用[\s\S];請參見原子:通用。

要匹配任何代碼點,您需要使用:1?

([\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF])

前面的模式工作原理如下:

([BMP code point]|[leading surrogate][trailing surrogate])

由于所有這些范圍都是不相交的,該模式將正確匹配 UTF-16 字符串中的代碼點。

一些庫可幫助處理 JavaScript 中的 Unicode:

  • Regenerate有助于生成像前面那樣的范圍,以匹配任何代碼單元。它旨在用作構建工具的一部分,但也可以動態(tài)工作,用于嘗試各種功能。

  • XRegExp是一個正則表達式庫,它有一個官方附加組件,可以通過以下三種構造之一匹配 Unicode 類別、腳本、塊和屬性:

    \p{...} \p{^...} \P{...}
    

例如,\p{Letter}匹配各種字母表中的字母,而\p{^Letter}\P{Letter}都匹配所有其他代碼點。第三十章包含了對 XRegExp 的簡要概述。

  • ECMAScript 國際化 API(請參見ECMAScript 國際化 API)提供了對 Unicode 的排序和搜索等功能。

推薦閱讀和章節(jié)來源

有關 Unicode 的更多信息,請參見以下內容:

  • 維基百科上有幾篇關于Unicode及其術語的好文章。

  • Unicode.org,Unicode 聯盟的官方網站,以及其FAQ也是很好的資源。

  • Joel Spolsky 的介紹性文章“每個軟件開發(fā)人員絕對必須了解的有關 Unicode 和字符集的絕對最低限度(沒有借口!)”很有幫助。

有關 JavaScript 中的 Unicode 支持的信息,請參見:

  • Mathias Bynens 的文章“JavaScript 的內部字符編碼:UCS-2 還是 UTF-16?”

  • 《JavaScript,正則表達式和 Unicode》由 Steven Levithan

致謝

以下人員為本章做出了貢獻:Mathias Bynens(@mathias),Anne van Kesteren(@annevk)和 Calvin Metcalf(@CWMma)。


1? 嚴格來說,任何Unicode 標量值。

第二十五章:ECMAScript 5 中的新功能

原文:25. New in ECMAScript 5

譯者:飛龍

協議:CC BY-NC-SA 4.0

本章列出了僅在 ECMAScript 5 中可用的功能。如果您必須使用舊版 JavaScript 引擎,您應該避免使用這些功能,或者通過庫啟用其中一些功能(稍后將進行描述)。請注意,通常情況下,本書假定您正在使用完全支持 ECMAScript 5 的現代引擎。

ECMAScript 5 規(guī)范包含了對其范圍的以下描述:

ECMAScript 的第五版(作為 ECMA-262 第 5 版發(fā)布)

  • 對已成為瀏覽器實現中常見的語言規(guī)范的實際解釋進行了編碼

  • 增加了對自第三版出版以來出現的新功能的支持。這些功能包括

    • 訪問器屬性,

    • 反射創(chuàng)建和檢查對象,

    • 程序控制屬性屬性,

    • 附加數組操作函數,

    • 對 JSON 對象編碼格式的支持,以及 x

    • 提供增強的錯誤檢查和程序安全性的嚴格模式。

新功能

ECMAScript 5 中包含的新功能如下:

嚴格模式(參見嚴格模式)

將以下行放在文件或函數的開頭可以打開所謂的嚴格模式,使 JavaScript 成為一個更干凈的語言,禁止一些功能,執(zhí)行更多檢查,并拋出更多異常:

'use strict';

訪問器(參見訪問器(Getter 和 Setter))

Getter 和 setter 允許您通過方法實現屬性的獲取和設置。例如,以下對象obj包含屬性foo的 getter:

> var obj = { get foo() { return 'abc' } };
> obj.foo
'abc'

語法更改

ECMAScript 5 包括以下語法更改:

保留字作為屬性鍵

您可以在點運算符之后使用保留字(例如newfunction)并且在對象文字中作為非引用的屬性鍵:

> var obj = { new: 'abc' };
> obj.new
'abc'

合法的尾隨逗號

對象文字和數組文字中的尾隨逗號是合法的。

多行字符串文字

如果通過反斜杠轉義行尾,字符串文字可以跨多行。

標準庫中的新功能

ECMAScript 5 為 JavaScript 的標準庫帶來了幾個新增功能。本節(jié)按類別列出了它們。

元編程

獲取和設置原型(參見獲取和設置原型):

  • Object.create()

  • Object.getPrototypeOf()

通過屬性描述符管理屬性屬性(參見屬性描述符):

  • Object.defineProperty()

  • Object.defineProperties()

  • Object.create()

  • Object.getOwnPropertyDescriptor()

列出屬性(參見迭代和屬性檢測):

  • Object.keys()

  • Object.getOwnPropertyNames()

保護對象(參見保護對象):

  • Object.preventExtensions()

  • Object.isExtensible()

  • Object.seal()

  • Object.isSealed()

  • Object.freeze()

  • Object.isFrozen()

新的Function方法(參見Function.prototype.bind(thisValue, arg1?, …, argN?)):

  • Function.prototype.bind()

新方法

字符串(參見第十二章):

  • 新方法String.prototype.trim()

  • 通過方括號操作符[...]訪問字符

新的Array方法(參見[Array Prototype Methods](ch18.html#array_prototype_methods “Array Prototype Methods”):

  • Array.isArray()

  • Array.prototype.every()

  • Array.prototype.filter()

  • Array.prototype.forEach()

  • Array.prototype.indexOf()

  • Array.prototype.lastIndexOf()

  • Array.prototype.map()

  • Array.prototype.reduce()

  • Array.prototype.some()

新的Date方法(參見Date Prototype Methods):

  • Date.now()

  • Date.prototype.toISOString()

JSON

對 JSON 的支持(參見第二十二章):

  • JSON.parse()(參見JSON.parse(text, reviver?))

  • JSON.stringify()(參見JSON.stringify(value, replacer?, space?))

  • 一些內置對象具有特殊的toJSON()方法:

  • Boolean.prototype.toJSON()

  • Number.prototype.toJSON()

  • String.prototype.toJSON()

  • Date.prototype.toJSON()

與舊版瀏覽器一起工作的提示

如果您需要與舊版瀏覽器一起工作,以下資源將非常有用:

  • Juriy Zaytsev(“kangax”)的兼容性表顯示了各種瀏覽器的各個版本支持 ECMAScript 5 的程度。

  • es5-shim 將 ECMAScript 5 的大部分(但不是全部)功能帶到只支持 ECMAScript 3 的瀏覽器中。

http://www.risenshineclean.com/news/10937.html

相關文章:

  • 龍華網站制作今天剛剛發(fā)生的新聞事故
  • wordpress電子書下載地址武漢seo推廣優(yōu)化
  • 織夢cms首頁模板文件是哪個網站優(yōu)化快速排名軟件
  • 蘿卜建站分類信息怎么樣引流加微信
  • 網站文章結構變更怎么做301愛論壇
  • 甘南網站建設百度熱搜榜怎么打開
  • 做房產抵押網站需要什么手續(xù)關鍵詞搜索量查詢工具
  • 商城網站開發(fā)需求seo智能優(yōu)化
  • 軟件開發(fā)屬于什么專業(yè)烏海網站seo
  • 大連公司網站開發(fā)西寧網站seo
  • wordpress網站搜不到seo教程視頻
  • 職業(yè)醫(yī)生繼續(xù)做學分市哪個網站長沙seo優(yōu)化報價
  • 做網站公司漢獅國外b站視頻推廣網站
  • 云南網站建設找天軟陜西seo推廣
  • django個人博客網站開發(fā)部署源碼寧波網站推廣公司價格
  • 企業(yè)網站優(yōu)化分為兩個方向杭州百度快照推廣
  • 洞涇做網站互聯網品牌的快速推廣
  • wordpress怎么修改代碼seo是什么平臺
  • 財務公司網站模板求好用的seo軟件
  • 微信網頁版如何識別二維碼seo平臺是什么
  • 做資訊網站要什么手續(xù)中國輿情在線
  • 傻瓜網站建設軟件蘭州網站seo
  • 專業(yè)的深圳網站建設公司免費的seo優(yōu)化工具
  • 南京做網站外包省委副書記
  • 網站建設指導全國seo公司排名
  • 網站標題正確書寫標準百度q3財報2022
  • 國外素材網站博客可以做seo嗎
  • 做網站怎么宣傳百度推廣怎么收費標準
  • 鄭州網絡重慶seo俱樂部聯系方式
  • 河南平安建設網站上海網站建設聯系方式