以前一種對ECMAScript的概念比較模糊,以及它跟Javascript、Jscript等腳本語言之間的關系不是太明白。本篇文章將就這些問題展示敘述。
業(yè)界所說的ECMAScript其實是指一種規(guī)范,或者說是一個標準。具體點來說,它其實就是一份文檔。其官網(wǎng)地址是http://www.ecmascript.org/。而我們通過所說的ECMAScript標準具體是指ECMA-262這份官方文檔。
目前ECMAScript釋出的最新版本是Fifth Edition of ECMA-262,不過本篇文章我們將暫時不會講ES6的相關東西。
這里有一份ES5的中文資料,可以認為其實官方文檔的翻譯版。
前面我們知道ECMAScript其實就是一份標準文檔,有ECMA標準化組織的TC39委員會制定的。但是這個組織只負責制定標準并不負責實現(xiàn)標準。那么是誰來實現(xiàn)這份標準呢?回答是各大瀏覽器廠商。
目前市面上常見的實現(xiàn)ECMAScript標準的腳本語言包括Javascript、Jscript等。同時這些標準實現(xiàn)由于一些歷史原因和客觀原因,各個版本之間、各個瀏覽器廠商的實現(xiàn)有一些差異,甚至是很大的差異。
關于ECMAScript、Javascript、Jscript這三者之間的關系,可以參閱三國志的故事(ECMAScript、JavaScript和JScript)。
ECMAScript 5.1就是我們常說的es5。它在2012年就已經被公開。時至今日,除了一些較低版本的瀏覽器,各大主流瀏覽器都已經實現(xiàn)支持了es5的絕大部分特性。
這里有一份不錯的關于es5的文檔,并附帶了許多有價值的注釋,有興趣可移步Annotated ECMAScript 5.1。
一般來說,除了針對個別特性的特殊說明,各大主流瀏覽器都支持es5,包括
其中IE9不支持es的嚴格模式,從IE10開始支持。Safari 5.1不支持Function.prototype.bind
。
下面我們將會針對ES5新增的特性或者API作一些簡要介紹。不過不會非常具體的講解,因為可能部分新增特性的講解可能都需要一篇文章的篇幅來描述。
Strict Mode, 即所謂的嚴格模式。嚴格模式的意義是為了提供一種更佳良好錯誤檢查機制,讓你規(guī)避掉一些語言本身的bad point。
比如在嚴格模式下,我們不可以使用一個未經聲明的變量??聪旅娴氖纠a,
"use strict"
function foo() {
var testVar = 4;
return testVar;
}
// This causes a syntax error.
testVar = 5;
上面的示例代碼中,我們試圖對一個未定義的變量進行賦值操作。在一般情況下(非嚴格模式)Javascript的執(zhí)行引擎會認為這個testVar
是一個全局變量,這一隱式轉換在某些時候將會帶來各種bug。而在嚴格模式下,你將會直接得到一個語法錯誤提示。
開啟嚴格模式的方法很簡單,只需要在文件的頂部寫上字符串use strict
即可。當然這需要執(zhí)行環(huán)境支持嚴格模式。另外由于use strict
其實是一個字符串常量。那么即使遇到不支持嚴格模式的環(huán)境,這行字符串只會被安全的忽略,不會帶來任何的問題。
關于嚴格模式的更多內容,可移步閱讀這篇文章Strict Mode (JavaScript)。
ES5提供一個內置的(全局)JSON對象,可用來序列化(JSON.stringfy
)和反序列化(parse
)對象為JSON格式。其一般性用法如下,
var test = {
"name": "gejiawen",
"age": 22
};
console.log(JSON.strinfy(test)); // '{"name": "gejiawen", "age": 22}'
console.log(JSON.parse('{"name": "larry"}')); // Object {name: "larry"}
JSON對象提供的parse
方法還提供第二個參數(shù),用于對具體的反序列化操作做處理。比如,
JSON.parse('{"name": "gejiawen", "age": 22, "lucky": "13"}', function(key, value) {
return typeof value === 'string' ? parseInt(value) : value;
});
這里我們在回調函數(shù)中對解析的每一對鍵值對作處理,如果其是一個數(shù)字字符串,我們則對其進行parseInt
操作,確保返回的value
必定是數(shù)值型的。
JSON對象提供的stringify
方法也會提供第二個參數(shù),用于解析的預處理,同時也會提供第三個參數(shù),用于格式化json字符串。比如,
var o = {
name: 'gejiawen',
age: 22,
lucky: '13'
};
var ret = JSON.stringify(o, function(key, value) {
return typeof value === 'string' ? undefined : value;
}, 4);
console.log(ret);
上面代碼在輸出時,得到的字符串將不會再呈現(xiàn)一行輸出,而是正常的格式化輸出,并采用4個space進行格式化。
另外,如果預處理函數(shù)的返回值為undefined
,則此鍵值對將不會包含在最終的JSON字符串中。所以上面代碼最終的結果是,
"{
"age": 22
}"
Object
接口對象 | 構造器 | 說明 |
---|---|---|
Object |
getPrototypeOf |
返回對象的原型 |
Object |
getOwnPropertyDescriptor |
返回對象自有屬性的屬性描述符 |
Object |
getOwnPropertyNames |
返回一個數(shù)組,包括對象所有自有屬性名稱集合(包括不可枚舉的屬性) |
Object |
create |
創(chuàng)建一個擁有置頂原型和若干個指定屬性的對象 |
Object |
defineProperty |
給對象定義一個新屬性,或者修改已有的屬性,并返回 |
Object |
defineProperties |
在一個對象上添加或修改一個或者多個自有屬性,并返回該對象 |
Object |
seal |
鎖定對象。阻止修改現(xiàn)有屬性的特性,并阻止添加新屬性。但是可以修改已有屬性的值。 |
Object |
freeze |
凍結對象,阻止對對象的一切操作。凍結對象將永遠不可變。 |
Object |
preventExtensions |
讓一個對象變的不可擴展,也就是永遠不能再添加新的屬性。 |
Object |
isSealed |
判斷對象是否被鎖定 |
Object |
isFrozen |
判斷對象是否被凍結 |
Object |
isExtensible |
判斷對象是否可以被擴展 |
Object |
keys |
返回一個由給定對象的所有可枚舉自身屬性的屬性名組成的數(shù)組 |
這里不打算對每個新增接口作詳細描述,不過比較常用的有如下幾個,
Object.create
Object.defineProperties
Object.keys
更多具體的用法請參閱Mozilla開發(fā)者文檔。
Array
接口對象 | 構造器 | 說明 |
---|---|---|
Array.prototype |
indexOf |
返回根據(jù)給定元素找到的第一個索引值,否則返回-1 |
Array.prototype |
lastIndexOf |
方法返回指定元素在數(shù)組中的最后一個的索引,如果不存在則返回 -1 |
Array.prototype |
every |
測試數(shù)組的所有元素是否都通過了指定函數(shù)的測試 |
Array.prototype |
some |
測試數(shù)組中的某些元素是否通過了指定函數(shù)的測試 |
Array.prototype |
forEach |
讓數(shù)組的每一項都執(zhí)行一次給定的函數(shù) |
Array.prototype |
map |
返回一個由原數(shù)組中的每個元素調用一個指定方法后的返回值組成的新數(shù)組 |
Array.prototype |
filter |
利用所有通過指定函數(shù)測試的元素創(chuàng)建一個新的數(shù)組,并返回 |
Array.prototype |
reduce |
接收一個函數(shù)作為累加器,數(shù)組中的每個值(從左到右)開始縮減,最終為一個值 |
Array.prototype |
reduceRight |
接受一個函數(shù)作為累加器,讓每個值(從右到左,亦即從尾到頭)縮減為一個值 |
新增的數(shù)組接口中,基本都是比較有用的接口。需要注意的一點是,有的數(shù)組方法是不返回新數(shù)組的,有的接口是返回一個新數(shù)組,就是說使用這些新接口時,需要注意一下方法的返回值。
另外Array
還有一個新增的接口,Array.isArray
。顯然此新增接口并不是實例方案,而是類似“靜態(tài)方法”一樣的存在。其作用很簡單,就是判斷某一對象是否為數(shù)組。
更多具體的用法請參閱Mozilla開發(fā)者文檔。
Function.prototype.bind
bind()方法會創(chuàng)建一個新函數(shù),稱為綁定函數(shù).當調用這個綁定函數(shù)時,綁定函數(shù)會以創(chuàng)建它時傳入 bind()方法的第一個參數(shù)作為 this,傳入 bind() 方法的第二個以及以后的參數(shù)加上綁定函數(shù)運行時本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調用原函數(shù)。
此方法的用法如下,
fun.bind(thisArg[, arg1[, arg2[, ...]]])
使用bind
可以為函數(shù)自定義this
指針。它的常見使用場景如下,
this.x = 9;
var module = {
x: 81,
getX: function() {
return this.x;
}
};
module.getX(); // 81
var getX = module.getX;
getX(); // 9, 因為在這個例子中,"this"指向全局對象
// 創(chuàng)建一個'this'綁定到module的函數(shù)
var boundGetX = getX.bind(module);
boundGetX(); // 81
Javascript中重新綁定this
變量的語法糖還有call
和apply
。不過bind
顯然與它們有著明顯的不同。bind
將會返回一個新的函數(shù),而call
或者apply
并不會返回一個新的函數(shù),它們將會使用新的this
指針直接進行函數(shù)調用。
更多建議: