简体   繁体   English

使用 Object.assign() 方法分配属性子集

[英]Assigning a subset of properties with the Object.assign() method

I am developing a chrome extension and I am creating a side panel using an iframe element.我正在开发 chrome 扩展,并且正在使用iframe元素创建侧面板。 I have an object that stores styles for the corresponding iframe :我有一个 object 存储 styles 对应的iframe

const sidePanelStyle = {
    background: 'white',
    // some other vars 
};

I create the iframe and assign my settings:我创建iframe并分配我的设置:

let sidePanel = document.createElement('iframe');
Object.assign(sidePanel.style, sidePanelStyle);

Everything works, but when before I did一切正常,但在我之前

sidePanel.style = Object.assign(sidePanel.style, sidePanelStyle);

it did not merge anything into the sidePanel.style (I expected that .assign() returns a merged object, as per MDN ).它没有将任何东西合并到sidePanel.style (我希望.assign()根据MDN返回合并的 object)。

I am new to JS, so the questions are:我是 JS 新手,所以问题是:

  1. What exactly I am missing with Object.assign() ? Object.assign()我到底缺少什么?
  2. What is the best practice to assign multiple settings properties to an object from the existing framework and what is the best practice to keep them in my source code (a separate module? one or more objects? etc.).从现有框架中将多个设置属性分配给 object 的最佳做法是什么?将它们保留在我的源代码中的最佳做法是什么(一个单独的模块?一个或多个对象?等等)。

While returning a merged object is redundant (the .assign() method merges everything into the first argument), I am still curios why it does not work, when the object is returned.虽然返回合并的 object 是多余的( .assign()方法将所有内容合并到第一个参数中),但当返回 object 时,我仍然很好奇为什么它不起作用。

 const sidePanelStyle = { background: 'gray', height: '100%', padding: '20px', width: '400px', position: 'fixed', top: '0px', right: '0px', zIndex: '9000000000000000000', }; let sidePanel = document.createElement('iframe'); // this works fine // Object.assign(sidePanel.style, sidePanelStyle); // this doesn't sidePanel.style = Object.assign(sidePanel.style, sidePanelStyle); document.body.appendChild(sidePanel);

This is a quirk of the style property on DOM elements, which is an unfortunate throwback to the early days of web browsers where things were added a bit...willy nilly with some very, very strange semantics.这是 DOM 元素的style属性的一个怪癖,不幸的是回到了 web 浏览器的早期阶段,其中添加了一些东西......不管用什么非常非常奇怪的语义。

When you read the style property of an element, you get an object that has properties for the inline styles.当您读取元素的style属性时,您会得到一个 object,它具有内联 styles 的属性。 But when you write to it, what you write is treated as though it were a string or null .但是当你它时,你写的东西被视为一个字符串或null (Althoughofficially , it's supposed to be read-only. It isn't treated that way in today's browsers, though.) (虽然正式,它应该是只读的。不过,在今天的浏览器中,它并没有被这样对待。)

Moral of the story: Don't write to it (unless you're writing null to completely clear it).故事的寓意:不要给它写信(除非你写null来完全清除它)。

So when you do:所以当你这样做时:

sidePanel.style = Object.assign(sidePanel.style, sidePanelStyle);

...what happens is: ...发生的是:

  1. The styles are successfully added to sidePanel.style , because Object.assign writes to the object given in its first argument, and then styles 已成功添加到sidePanel.style ,因为Object.assign写入其第一个参数中给出的 object,然后

  2. The object it returns (also sidePanel.style ) is converted to string and interpreted as style properties.它返回的 object (也是sidePanel.style )被转换为字符串并解释为样式属性。 (Although, again, it's supposed to be read-only.) (虽然,同样,它应该是只读的。)

But when you convert it to string, the resulting string is "[object CSSStyleDeclaration]" , which can't be converted to styles, so you wipe out the styles on the element.但是当你将其转换为字符串时,得到的字符串是"[object CSSStyleDeclaration]" ,不能转换为 styles,所以你将元素上的 styles 擦掉。

Here's a simpler demonstration of what's going on:这是一个更简单的演示:

 const example = document.getElementById("example"); example.style.color = "blue"; setTimeout(function() { console.log("example.style.color before: " + example.style.color); // Assigning it to itself, which is effectively what // your code with `Object.assign` was doing example.style = example.style; console.log("example.style.color after: " + example.style.color); console.log("String(example.style): " + String(example.style)); }, 800);
 <div id="example">This is the example div</div>

As you've seen, there's no reason to write back to it anyway, as the properties are added to it because it's the first argument to Object.assign .如您所见,无论如何都没有理由回写它,因为属性已添加到其中,因为它是Object.assign的第一个参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM