Tim Chrome baru-baru ini mengumumkan bahwa kami memindahkan properti DOM ke rantai prototipe. Perubahan ini, yang diterapkan di Chrome 43 - (Beta mulai pertengahan April 2015) - membuat Chrome lebih sesuai dengan Spesifikasi IDL Web dan implementasi browser lainnya, seperti IE dan Firefox. Edit: diperjelas Browser berbasis WebKit lama, saat ini tidak kompatibel dengan spesifikasi, tetapi Safari sekarang kompatibel.
Perilaku baru ini positif dalam banyak hal. Persyaratan ini:
- Meningkatkan kompatibilitas di seluruh web (IE dan Firefox sudah melakukannya) melalui kepatuhan terhadap spesifikasi.
- Memungkinkan Anda membuat pengambil/penyemat secara konsisten dan efisien di setiap Objek DOM.
- Meningkatkan kemampuan peretasan pemrograman DOM. Misalnya, Anda dapat menerapkan polyfill yang memungkinkan Anda mengemulasi fungsi yang tidak ada di beberapa browser dan library JavaScript secara efisien yang mengganti perilaku atribut DOM default.
Misalnya, spesifikasi W3C hipotetis menyertakan beberapa fungsi baru yang disebut isSuperContentEditable
dan Browser Chrome tidak menerapkannya, tetapi Anda dapat "mem-polyfill" atau mengemulasi fitur dengan library. Sebagai developer library, Anda tentu ingin menggunakan prototype
sebagai berikut untuk membuat polyfill yang efisien:
Object.defineProperty(HTMLDivElement.prototype, "isSuperContentEditable", {
get: function() { return true; },
set: function() { /* some logic to set it up */ },
});
Sebelum perubahan ini - untuk konsistensi dengan properti DOM lainnya di Chrome - Anda harus membuat properti baru di setiap instance, yang untuk setiap HTMLDivElement
di halaman akan sangat tidak efisien.
Perubahan ini penting untuk konsistensi, performa, dan standardisasi platform web, tetapi dapat menyebabkan beberapa masalah bagi developer. Jika Anda mengandalkan perilaku ini karena kompatibilitas lama antara Chrome dan WebKit, sebaiknya periksa situs Anda dan lihat ringkasan perubahan di bawah.
Ringkasan perubahan
Menggunakan hasOwnProperty
pada instance Objek DOM kini akan menampilkan false
Terkadang developer akan menggunakan hasOwnProperty
untuk memeriksa keberadaan properti pada objek. Hal ini tidak akan berfungsi lagi sesuai spesifikasi karena atribut DOM kini menjadi bagian dari rantai prototipe dan hasOwnProperty
hanya memeriksa objek saat ini untuk melihat apakah atribut tersebut ditentukan di dalamnya.
Sebelum dan termasuk Chrome 42, kode berikut akan menampilkan true
.
> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");
true
Di Chrome 43 dan yang lebih baru, parameter ini akan menampilkan false
.
> div = document.createElement("div");
> div.hasOwnProperty("isContentEditable");
false
Artinya, jika Anda ingin memeriksa apakah isContentEditable
tersedia di elemen, Anda harus memeriksa prototipe di objek HTMLElement. Misalnya, HTMLDivElement
mewarisi dari HTMLElement
yang menentukan properti isContentEditable
.
> HTMLElement.prototype.hasOwnProperty("isContentEditable");
true
Anda tidak terikat untuk menggunakan hasOwnProperty
. Sebaiknya gunakan operand in
yang jauh lebih sederhana karena akan memeriksa properti di seluruh rantai prototipe.
if("isContentEditable" in div) {
// We have support!!
}
Object.getOwnPropertyDescriptor pada Instance Objek DOM tidak akan lagi menampilkan deskripsi properti untuk Atribut
Jika situs Anda perlu mendapatkan deskripsi properti untuk atribut pada Objek DOM, Anda kini harus mengikuti rantai prototipe.
Jika ingin mendapatkan deskripsi properti di Chrome 42 dan yang lebih lama, Anda harus melakukan:
> Object.getOwnPropertyDescriptor(div, "isContentEditable");
Object {value: "", writable: true, enumerable: true, configurable: true}
Chrome 43 dan yang lebih baru akan menampilkan undefined
dalam skenario ini.
> Object.getOwnPropertyDescriptor(div, "isContentEditable");
undefined
Artinya, untuk mendapatkan deskripsi properti untuk properti isContentEditable
, Anda harus mengikuti rantai prototipe sebagai berikut:
> Object.getOwnPropertyDescriptor(HTMLElement.prototype, "isContentEditable");
Object {get: function, set: function, enumerable: false, configurable: false}
JSON.stringify tidak akan lagi melakukan serialisasi Atribut DOM
JSON.stringify
tidak melakukan serialisasi properti DOM yang ada di prototipe. Misalnya, hal ini dapat memengaruhi situs Anda jika Anda mencoba melakukan serialisasi objek seperti PushSubscription Notifikasi Push.
Chrome 42 dan yang lebih lama, hal berikut akan berfungsi:
> JSON.stringify(subscription);
{
"endpoint": "https://something",
"subscriptionId": "SomeID"
}
Chrome 43 dan yang lebih baru tidak akan melakukan serialisasi properti yang ditentukan pada prototipe dan Anda akan mendapatkan objek kosong.
> JSON.stringify(subscription);
{}
Anda harus menyediakan metode serialisasi Anda sendiri, misalnya, Anda dapat melakukan hal berikut:
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);
Menulis ke properti hanya baca dalam mode ketat akan menampilkan error
Menulis ke properti hanya baca seharusnya akan menampilkan pengecualian saat Anda menggunakan mode ketat. Misalnya, perhatikan hal berikut:
function foo() {
"use strict";
var d = document.createElement("div");
console.log(d.isContentEditable);
d.isContentEditable = 1;
console.log(d.isContentEditable);
}
Di Chrome 42 dan yang lebih lama, fungsi akan berlanjut dan terus mengeksekusi fungsi secara diam-diam, meskipun isContentEditable
tidak akan diubah.
// Chrome 42 and earlier behavior
> foo();
false // isContentEditable
false // isContentEditable (after writing to read-only property)
Sekarang di Chrome 43 dan yang lebih baru, akan ada pengecualian yang ditampilkan.
// Chrome 43 and onwards behavior
> foo();
false
Uncaught TypeError: Cannot set property isContentEditable of #<HTMLElement> which has only a getter
Saya mengalami masalah, apa yang harus saya lakukan?
Ikuti panduannya, atau tulis komentar di bawah dan mari kita bicarakan.
Saya melihat situs yang bermasalah, apa yang harus saya lakukan?
Pertanyaan bagus. Sebagian besar masalah pada situs akan didasarkan pada fakta bahwa situs telah memilih untuk melakukan deteksi kehadiran Atribut dengan metode getOwnProperty
. Hal ini biasanya dilakukan jika pemilik situs hanya menargetkan browser WebKit lama. Ada beberapa hal yang dapat dilakukan developer:
- Laporkan masalah tentang situs yang terpengaruh di issue tracker kami (Chrome)
- Ajukan masalah di radar WebKit dan referensikan https://bugs.webkit.org/show_bug.cgi?id=49739
Saya umumnya tertarik untuk mengikuti perubahan ini
- Bug asli dari tahun 2010: https://bugs.chromium.org/p/chromium/issues/detail?id=43394 - catatan: memiliki sebagian besar pekerjaan di dalamnya.
- Peninjauan Kode untuk commit