翻譯自DOM Attributes now on the prototype chain
不過文章中的有一些部分確實難以理解,若是有大神能看出我這裏出錯了,請及時的告訴我,謝謝javascript
Chrome團隊最近宣佈咱們將DOM屬性移動到了原型鏈上。這個變化將會應用到在Chrome 43上。html
這些新的行爲將會在如下一個方面帶來好處,以下:html5
例如,假設W3C規範包括一些新的功能,叫作isSuperContentEditable
,Chrome瀏覽器並無採用它,可是它能夠經過ployfill或者用一些庫來模仿新的功能。做爲一個庫的開發人員,你可能天然的想去使用prototype
去模仿新的功能。java
js
Object.defineProperty(HTMLDivElement.prototype, "isSuperContentEditable", { get: function() { return true; }, set: function() { /* some logic to set it up */ }, });
在更新以前,爲了保證chrome中和其餘DOM元素屬性的一致性,你不得不建立一個新的屬性在每個實例上,這將會給頁面中的每個HTMLDivElement
加上那個屬性,這是很是低效的。git
此次更新爲了一致性、高性能和標準化的web平臺來講是很是重要的。然而你也能夠發起一些issues給開發者。若是你信賴這種由於這是chrome和webkit的遺產,咱們鼓勵你去檢查一下你的網站,而且看一下以後的內容。github
如今使用
hasOwnProperty
在一個DOM元素上將會返回false
web
有時候開發者就會使用hasOwnProperty
去檢查是否一個屬性在一個對象上。如今將不會像以前的那樣。由於DOM屬性如今是原型鏈的一部分,而且hasOwnProperty
僅僅檢查當前的對象是否認義了它。chrome
在Chrome 42 中下面將會返回true
api
js
> div = document.createElement("div"); > div.hasOwnProperty("isContentEditable"); true
在Chrome 43中前面的將會返回false
瀏覽器
> div = document.createElement("div"); > div.hasOwnProperty("isContentEditable"); false
這個如今意思着若是你想要檢查isContentEditable
是否在元素上可用,你須要檢查html元素對象的原型上。
假設,HTMLDivElement
繼承自HTMLElement
。而且HTMLElement
定義了isContentEditable
屬性
js
> HTMLElement.prototype.hasOwnProperty("isContentEditable"); true
你沒必要必定要使用hasOwnProperty
。咱們推薦去使用很是簡單的in
操做符。就像下面這個代碼去檢查是否一個屬性在整個原型鏈中存在。
js
if("isContentEditable" in div) { // We have support!! }
Object.getOwnPropertyDescript
在DOM實例上將再也不返回對這個屬性的描述
若是你的網站須要得到屬性的描述符在一個DOM對象上,你如今須要在原型鏈上進行操做。
若是你想要得到屬性的描述符在Chrome 42 或者更早,你能夠這樣作
> Object.getOwnPropertyDescriptor(div, "isContentEditable"); Object {value: "", writable: true, enumerable: true, configurable: true}
在Chrome 43中將會返回 undefined
在這斷代碼中
> Object.getOwnPropertyDescriptor(div, "isContentEditable"); undefined
這將意味着,想要得到屬性的描述符,你須要在原型鏈上進行操做,以下:
> Object.getOwnPropertyDescriptor(HTMLElement.prototype, "isContentEditable"); Object {get: function, set: function, enumerable: false, configurable: false}
JSON.stringify
將再也不序列化DOM屬性
JSON.stringify
不會序列化DOM在原型上的屬性。
例如,這個將會影響你的網站若是你嘗試去序列化一個推送提醒對象 PushSubscription
Chrome 43 或者更早的版本,將會按照下面的結果返回
> JSON.stringify(subscription); { "endpoint": "https://something", "subscriptionId": "SomeID" }
Chrome 43 按照上面的代碼將不會序列化定義在原型鏈上的屬性,而且返回一個空的對象
> JSON.stringify(subscription); {}
你將要不得不提供本身的格式化方法,例如,你能夠這樣弄:
function stringifyDOMObject(object) { function deepCopy(src) { if (typeof src != "object") return src; var dst = Array.isArray(src) ? [] : {}; for (var property in src) { dst[property] = deepCopy(src[property]); } return dst; } return JSON.stringify(deepCopy(object)); } var s = stringifyDOMObject(domObject);
在嚴格模式下,修改只讀屬性將會拋出錯誤
當你使用嚴格模式的時候,修改只讀屬性將會拋出一個錯誤。
例如:
function foo() { "use strict"; var d = document.createElement("div"); console.log(d.isContentEditable); d.isContentEditable = 1; console.log(d.isContentEditable); }
Chrome 43 或者更早版本,函數將會繼續的執行,而且不會拋出任何異常,儘管isContentEditable
並不會改變。
// Chrome 42 and earlier behavior > foo(); false // isContentEditable false // isContentEditable (after writing to read-only property)
如今在Chrome 43 中將會拋出一個異常。
// Chrome 43 and onwards behavior > foo(); false Uncaught TypeError: Cannot set property isContentEditable of #<HTMLElement> which has only a getter
Chrome 43 關於DOM的更新就到這裏結束了,若是你們對我翻譯的這篇文章若是有任何疑問,歡迎提意見。