JavaScript >> Javascript 文檔 >  >> Tags >> document

Internet Explorer 8 文檔模式如何影響 JavaScript

在之前的一篇文章中,我談到了 Internet Explorer 8 的各種瀏覽器和文檔模式。大多數人都非常熟悉各種文檔模式如何影響 CSS 的實現方式的佈局,但丟失的是文檔模式如何影響瀏覽器中的核心 JavaScript 引擎。這些變化有些微妙,但在使用 Internet Explorer 8 時了解這些變化很重要。

幾年前,微軟發表了一篇名為《JScript Deviations from ES3》的論文,其中概述了 JScript 引擎(Internet Explorer 的 JavaScript 的一個強大功能)偏離 ECMAScript 3 標準的方式。這些偏差在某種程度上是無害的,但很可能你在過去的某個時候被其中的一個或多個所咬傷。在微軟試圖讓 Internet Explorer 8 更符合標準的過程中,圍繞 CSS 出現的同樣問題也出現在 JavaScript 周圍。他們可以修復 JScript 中的偏差,但如果瀏覽器在 IE5 或 IE7 文檔模式下運行,則可能會出現問題,因為這些修復可能與針對這些瀏覽器的代碼不兼容。

Microsoft 選擇為 Internet Explorer 8 創建 JScript 引擎的版本化功能。對於 IE5 和 IE7 文檔模式,JScript 引擎的行為與實際 Internet Explorer 7 中的一樣,完全與 ECMAScript 3 有所有偏差。在 IE8 文檔模式下,偏差消失了,您將獲得 JScript 引擎的全部功能。

原生 JSON

Internet Explorer 8 的 JScript 引擎實現了原生 JSON object 由 ECMAScript 5 定義的對象。但是,該對象僅在頁面以 IE8 文檔模式運行時存在。這包括全局 JSON 對像以及用於 JSON 功能的方法:

  • Date.prototype.toJSON()
  • Number.prototype.toJSON()
  • String.prototype.toJSON()
  • Boolean.prototype.toJSON()

JSON object 和 IE5 或 IE7 文檔模式下的這些方法是未定義的。

注意: 即使 Date.prototype.toJSON() 在 IE8 文檔中支持,Date.prototype.toISOString() 未實施。這很奇怪,因為它們返回相同的值。

DOM 獲取器/設置器

JScript 引擎更令人好奇的方面之一是它實現了 ECMAScript 5 的 getter 和 setter,但僅適用於 DOM 對象,而不適用於原生 JavaScript 對象。實現由 Object.defineProperty() 的半生不熟版本組成 和 Object.getOwnPropertyDescriptor() 主要支持 get 和 set 屬性。例如:

Object.defineProperty(document.body, "active", {
    set: function(value){
        document.body.className = (value !== false) ? "active" : "";
    },

    get: function(){
        return document.body.className == "active";
    }

});

var descriptor = Object.getOwnPropertyDescriptor(document.body, "innerHTML");
alert(descriptor.get);   //displays function

這兩種方法都只在IE8文檔模式下可用,在其他文檔模式下不存在。

數組

JScript 實現真正崩潰的領域之一是處理數組。數組與 ECMAScript 3 標準的偏差最大,並且一直是開發人員頭疼的根源。首先,如果 undefined 傳入 join() ,參數被翻譯成字符串“undefined”,用於連接項目。例如:

var colors = ["red", "green", "blue"];
alert(colors.join(undefined));    //"redundefinedgreenundefinedblue" in IE7

在 IE8 文檔模式下運行時,值為 undefined 被忽略並使用默認分隔符(逗號)。

unshift() 將一個項目推到數組前面的方法在 JScript 中也有偏差。添加項目後,它沒有返回數組的長度,而是簡單地返回 undefined .在 IE8 文檔模式下,此問題已得到修復,因此 unshift() 正確返回數組長度。

數組的最後一個重大變化是能夠正確繼承 Array 類型。 Dean Edwards 有一篇關於嘗試創建 Array 子類型的完整帖子 以及他遇到的問題。最大的問題是分配 Array 的實例 成為另一個構造函數的原型意味著 length 財產將不再起作用。考慮以下幾點:

function MyArray(){
}

MyArray.prototype = new Array();
MyArray.prototype.get = function(i){
    return this[i];
};

var colors = new MyArray();
colors.push("red");
colors.push("green");
colors.sort();
alert(colors.get(0));    //"green"
alert(colors.length);    //in IE7, outputs "0"; in IE8, outputs "2"

在 Internet Explorer 8 之前的版本中,length 任何 Array 的屬性 後代類型不會自動更改,因此繼承僅對非 IE 瀏覽器真正有用。但是,在 IE8 文檔模式下,length 屬性的工作方式與其他瀏覽器一樣,而 IE5 和 IE7 文檔模式使用舊的偏離行為。

其他修復

有一小部分無法在邏輯上真正分類的修復,但仍然有助於 JScript 與其他 JavaScript 實現更加一致。首先是對象文字現在允許尾隨逗號。在 Internet Explorer 8 之前,以下情況會導致解析錯誤:

var object = {
    name: "value",
};

最後一個屬性值後面的逗號是 ECMAScript 3 語法明確允許的,並且在所有其他瀏覽器中都是允許的。 IE8 文檔模式現在也正確支持此語法(其他文檔模式仍然會拋出錯誤)。

另一個不錯的改進是 IE8 文檔模式現在允許通過括號表示法訪問字符串中的字符:

var s = "Hello world!";
alert(s[0]);    //"H"

這使 JScript 與其他 JavaScript 引擎保持一致; IE5 和 IE7 文檔模式仍將返回 undefined .

另外兩個可能不會影響您但值得注意的變化:

  • Number.prototype.toPrecision() 用於undefined時拋出錯誤 已傳入。IE8 文檔模式現在默認調用 Number.prototype.toString() 在這種情況下。
  • Error.prototype.toString() 已正確實施以提供更好的錯誤消息。

結論

IE8 文檔模式比 Internet Explorer 7 提供了大量改進,不僅在 CSS 方面,而且在 JavaScript 方面。如果您希望編寫盡可能符合標準的代碼,請確保您的頁面在 Internet Explorer 8 上以 IE8 文檔模式運行(有關詳細信息,請參閱我以前的帖子)。使 JScript 與其他 JavaScript 引擎保持一致是非常重要的一步。可惜這些細節在 Internet Explorer 8 公告中幾乎被忽略了。


Tutorial JavaScript 教程
  1. 使用 django 構建新聞應用

  2. 使用 Jest 測試 React App 的實用方法 - 第 1 部分

  3. 只允許英文字符和數字進行文本輸入

  4. 帶有 RxWeb 的 Angular 11+ FormGroup 數組

  5. 宣布 NodeSource CFP - 召集所有 Node.js 和 JavaScript 演講者

  6. 使用 Netlify、Zapier 和 SendGrid 將聯繫表電子郵件路由到不同的地址

  7. 我想重定向到對條件做出反應的新頁面

  1. 如何在 vue.js 中製作動態麵包屑?

  2. 修復 Chrome80 SameSite 問題

  3. 更改嵌入組件的 prop 值

  4. 使用 Apollo 從 Node.js 查詢 GraphQL

  5. DOM 中的樣式更改 - JavaScript 系列 - 第 25 部分

  6. javascript中的for..in產生與forEach和for循環不同的輸出?

  7. 兩種類型的功能並有區別

  1. 如何檢查瀏覽器是否是 Chrome Javascript?

  2. 使用 Javascript 深入研究數據結構 - 鍊錶

  3. Redux 與 React 上下文 API

  4. 如何使用 HTML、CSS 和 Vanilla JavaScript 構建天氣轉換器(第 4 部分-部署)