ECMAScript5.1及其新增API簡介

2018-06-09 18:03 更新

以前一種對ECMAScript的概念比較模糊,以及它跟Javascript、Jscript等腳本語言之間的關系不是太明白。本篇文章將就這些問題展示敘述。

什么是ECMAScript

業(yè)界所說的ECMAScript其實是指一種規(guī)范,或者說是一個標準。具體點來說,它其實就是一份文檔。其官網(wǎng)地址是http://www.ecmascript.org/。而我們通過所說的ECMAScript標準具體是指ECMA-262這份官方文檔。

目前ECMAScript釋出的最新版本是Fifth Edition of ECMA-262,不過本篇文章我們將暫時不會講ES6的相關東西。

這里有一份ES5的中文資料,可以認為其實官方文檔的翻譯版。

標準的實現(xiàn)

前面我們知道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

ECMAScript 5.1就是我們常說的es5。它在2012年就已經被公開。時至今日,除了一些較低版本的瀏覽器,各大主流瀏覽器都已經實現(xiàn)支持了es5的絕大部分特性。

這里有一份不錯的關于es5的文檔,并附帶了許多有價值的注釋,有興趣可移步Annotated ECMAScript 5.1。

瀏覽器支持

一般來說,除了針對個別特性的特殊說明,各大主流瀏覽器都支持es5,包括

  • Chrome 13+
  • Firefox 4+
  • Safari 5.1*
  • IE 9*

其中IE9不支持es的嚴格模式,從IE10開始支持。Safari 5.1不支持Function.prototype.bind。

ES5新特性簡介

下面我們將會針對ES5新增的特性或者API作一些簡要介紹。不過不會非常具體的講解,因為可能部分新增特性的講解可能都需要一篇文章的篇幅來描述。

Strict Mode

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

JSON對象

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變量的語法糖還有callapply。不過bind顯然與它們有著明顯的不同。bind將會返回一個新的函數(shù),而call或者apply并不會返回一個新的函數(shù),它們將會使用新的this指針直接進行函數(shù)調用。

參考列表

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號