【翻译】Chrome 43 部分更新:如今 DOM 的属性将会在原型链上

翻译自DOM Attributes now on the prototype chain
不过文章中的有一些部分确实难以理解,若是有大神能看出我这里出错了,请及时的告诉我,谢谢javascript

Chrome团队最近宣布咱们将DOM属性移动到了原型链上。这个变化将会应用到在Chrome 43上。html

这些新的行为将会在如下一个方面带来好处,以下:html5

  • 提升兼容性,IE和Firefox已经遵循了标准
  • 容许你一向而且高效的在DOM对象上建立getter或setter
  • 能够提升程序的hack的能力。例如,他容许你用一些兼容性工具,用来高效的模拟在一些浏览器上丢失的功能。而且javascript库也能够重写默认的DOM属性。

例如,假设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元素上将会返回falseweb

有时候开发者就会使用hasOwnProperty去检查是否一个属性在一个对象上。如今将不会像以前的那样。由于DOM属性如今是原型链的一部分,而且hasOwnProperty仅仅检查当前的对象是否认义了它。chrome

在Chrome 42 中下面将会返回trueapi

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的更新就到这里结束了,若是你们对我翻译的这篇文章若是有任何疑问,欢迎提意见。

相关文章
相关标签/搜索