簡體   English   中英

為什么在“凍結” document.body對象之后,可以修改其屬性?

[英]Why after “freezing” the document.body object, I can modify its properties?

Object.freeze()

不能更改數據屬性的值。 訪問器屬性(獲取器和設置器)的工作原理相同(並且仍然給人一種幻想,即您正在更改值)。 請注意,除非將對象值凍結,否則仍可以對其進行修改。 作為對象,可以凍結數組,此后不能更改其元素。 也不能添加或刪除任何元素。

 'use strict' document.body.innerHTML = "Hello#1"; var frozen = Object.freeze(document.body); document.body = frozen; console.log("Same frozen body (First):", document.body === frozen) console.log(document.body['innerHTML']); // Why I can modify this property? document.body.innerHTML = "Hello#2"; console.log("Same frozen body (Second):", document.body === frozen); console.log(document.body['innerHTML']); 

此代碼段使用gettersetter (此方法失敗)

 'use strict' var myObj = { a: "Ele#1", get innerHTML() { return this.a; }, set innerHTML(html) { this.a = html; } } myObj = Object.freeze(myObj); myObj.innerHTML = "Ele"; console.log(myObj); 

為什么在“凍結”主體對象之后,可以修改其屬性? 例如, innerHTML

可能我缺少信息,我不知道!

innerHTML是訪問器屬性。 如果在控制台上調試document.body並向下鑽取原型鏈,則可以在Element中將其定義為get innerHTML()set innerHTML()

這是一個如何實現相同目標的准系統示例:

var myObj = (function() {
    var html = null;

    return {
        get innerHTML() { return html; },
        set innerHTML(value) { html = value; }
    };
})();

訪問器屬性(獲取器和設置器)的工作原理相同(並且仍然給人一種幻想,即您正在更改值)。

正如您在下面以及在規范中可以看到的那樣, innerHTML確實是訪問器屬性:

 function getPropertyDescriptor(object, property) { while (typeof object === 'object' && object !== null) { const descriptor = Object.getOwnPropertyDescriptor(object, property) if (descriptor) { return descriptor } object = Object.getPrototypeOf(object) } } const desc = getPropertyDescriptor(document.body, 'innerHTML') console.log(desc) 

修改您的簡化示例以使用WeakMap代替屬性,可以使其工作:

 'use strict' const Element = (() => { const weakPrivate = new WeakMap() return class Element { constructor () { weakPrivate.set(this, { innerHTML: 'initial' }) } get innerHTML () { return weakPrivate.get(this).innerHTML } set innerHTML (value) { return weakPrivate.get(this).innerHTML = value } } })() let object = new Element() Object.freeze(object) console.log(object.innerHTML) object.innerHTML = 'new value' console.log(object.innerHTML) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM