使用 Object.assign() 方法分配属性子集
Assigning a subset of properties with the Object.assign() method
我正在开发 chrome 扩展,我正在使用 iframe
元素创建侧面板。
我有一个对象存储相应 iframe
:
的样式
const sidePanelStyle = {
background: 'white',
// some other vars
};
我创建 iframe
并分配我的设置:
let sidePanel = document.createElement('iframe');
Object.assign(sidePanel.style, sidePanelStyle);
一切正常,但在我之前
sidePanel.style = Object.assign(sidePanel.style, sidePanelStyle);
它没有将任何东西合并到 sidePanel.style
中(我预计 .assign()
returns 是一个合并的对象,根据 MDN)。
我是 JS 新手,所以问题是:
Object.assign()
我到底错过了什么?
- 将多个设置属性分配给现有框架中的对象的最佳做法是什么,将它们保留在我的源代码中的最佳做法是什么(一个单独的
模块?一个或多个对象?等)。
虽然返回合并的对象是多余的(.assign()
方法将所有内容合并到第一个参数中),但我仍然很好奇为什么它在返回对象时不起作用。
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);
这是 style
属性 在 DOM 元素上的一个怪癖,这是对早期 Web 浏览器添加了一些东西的不幸倒退... willy nilly 有一些非常非常奇怪的语义。
当您 读取 元素的 style
属性 时,您会得到一个具有内联样式属性的对象。但是当你向它写入时,你写入的内容将被视为字符串或null
。 (尽管 officially,它应该是只读的。但是在今天的浏览器中它不是这样处理的。)
这个故事的寓意:不要写它(除非你写 null
来完全清除它)。
所以当你这样做时:
sidePanel.style = Object.assign(sidePanel.style, sidePanelStyle);
...发生的事情是:
样式成功添加到sidePanel.style
,因为Object.assign
写入第一个参数给定的对象,然后
它returns(也sidePanel.style
)的对象被转换为字符串并解释为样式属性。 (不过,同样,它应该是只读的。)
但是当你把它转换成字符串时,得到的字符串是"[object CSSStyleDeclaration]"
,它不能转换成样式,所以你擦掉了元素上的样式。
这里有一个更简单的演示:
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>
如您所见,无论如何都没有理由回写它,因为属性已添加到它,因为它是 Object.assign
.
的第一个参数
我正在开发 chrome 扩展,我正在使用 iframe
元素创建侧面板。
我有一个对象存储相应 iframe
:
const sidePanelStyle = {
background: 'white',
// some other vars
};
我创建 iframe
并分配我的设置:
let sidePanel = document.createElement('iframe');
Object.assign(sidePanel.style, sidePanelStyle);
一切正常,但在我之前
sidePanel.style = Object.assign(sidePanel.style, sidePanelStyle);
它没有将任何东西合并到 sidePanel.style
中(我预计 .assign()
returns 是一个合并的对象,根据 MDN)。
我是 JS 新手,所以问题是:
Object.assign()
我到底错过了什么?- 将多个设置属性分配给现有框架中的对象的最佳做法是什么,将它们保留在我的源代码中的最佳做法是什么(一个单独的 模块?一个或多个对象?等)。
虽然返回合并的对象是多余的(.assign()
方法将所有内容合并到第一个参数中),但我仍然很好奇为什么它在返回对象时不起作用。
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);
这是 style
属性 在 DOM 元素上的一个怪癖,这是对早期 Web 浏览器添加了一些东西的不幸倒退... willy nilly 有一些非常非常奇怪的语义。
当您 读取 元素的 style
属性 时,您会得到一个具有内联样式属性的对象。但是当你向它写入时,你写入的内容将被视为字符串或null
。 (尽管 officially,它应该是只读的。但是在今天的浏览器中它不是这样处理的。)
这个故事的寓意:不要写它(除非你写 null
来完全清除它)。
所以当你这样做时:
sidePanel.style = Object.assign(sidePanel.style, sidePanelStyle);
...发生的事情是:
样式成功添加到
sidePanel.style
,因为Object.assign
写入第一个参数给定的对象,然后它returns(也
sidePanel.style
)的对象被转换为字符串并解释为样式属性。 (不过,同样,它应该是只读的。)
但是当你把它转换成字符串时,得到的字符串是"[object CSSStyleDeclaration]"
,它不能转换成样式,所以你擦掉了元素上的样式。
这里有一个更简单的演示:
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>
如您所见,无论如何都没有理由回写它,因为属性已添加到它,因为它是 Object.assign
.