Javascript 为什么';定义computedStyle work属性的访问器描述符?

Javascript 为什么';定义computedStyle work属性的访问器描述符?,javascript,html,Javascript,Html,我想通过class属性上的更改来检测displayCSS属性上的值更改,我想出了下面的代码片段 我知道getComputedStyle返回一个只读的liveCSSStyleDeclaration对象,但是当元素的样式更改时,对象会自动更新,我假设它会以某种方式分配其属性 但它并没有叫能手和二传手。为什么会发生这种情况?当它是只读的时候,它如何分配它的属性 let parent=document.querySelector(“.parent”); 让child=parent.querySelec

我想通过
class
属性上的更改来检测
display
CSS属性上的值更改,我想出了下面的代码片段

我知道
getComputedStyle
返回一个只读的live
CSSStyleDeclaration
对象,但是当元素的样式更改时,对象会自动更新,我假设它会以某种方式分配其属性

但它并没有叫能手和二传手。为什么会发生这种情况?当它是只读的时候,它如何分配它的属性

let parent=document.querySelector(“.parent”);
让child=parent.querySelector(“.child”);
let style=getComputedStyle(子级);
让显示=符号(“显示”);
style[display]=style.display;
Object.defineProperty(样式,“显示”{
得到(){
log(“getter”);
返回样式[显示];
},
设置(值){
日志(“setter”,值);
样式[显示]=值;
}
});
let button=document.querySelector(“按钮”);
按钮。addEventListener(“单击”,()=>{
child.classList.toggle(“隐藏”);
});
.child{
高度:100px;
背景色:#80a0c0;
}
.隐藏{
显示:无;
}
切换

主机提供的对象不需要很好地播放。:-)(甚至在主机提供的对象上也有。)

尽管在Chrome和相关浏览器上,该对象声称
display
属性是一个简单的数据属性(在Firefox和Legacy Edge上,它更合理,是原型上的访问器属性):

let style=getComputedStyle(document.querySelector(“.child”);
让kind=“拥有”;
做{
const descr=Object.getOwnPropertyDescriptor(样式,“显示”);
如果(描述){
日志(种类+“属性:”,描述);
打破
}
如果(种类=“自己的”){
kind=“原型”;
}否则{
种类+=“'的原型”;
}
style=Object.getPrototypeOf(style);
}while(风格)
.child{
高度:100px;
背景色:#80a0c0;
}
.隐藏{
显示:无;
}
切换

我可能会错过一些东西,但我不明白为什么您会认为它必须赋值

它只是一个getter,每次调用内部算法检查值是否已更改,如果已更改,它将触发recalc,以便所有脏CSS属性现在都是最新的,并最终返回当前值

更改CSS值本身不会设置对象的属性,它只会更改内部状态,该状态将在下次由getter获取

这方面的一个基本实现可以是

let internal_state='foo';
常量计算样式={
get display(){return internal_state;},
设置显示(值){console.log('setting');}//从未调用
};
console.log(computedStyle.display);//“福”
//触发更改的内容,例如切换类
内部_状态='bar';

console.log(computedStyle.display);//bar“”
可能是因为它是一个特殊的主机提供的对象,不必符合所有Javascript的正常规则。尽管它们使用相同的接口,
getComputedStyle(element)
element。style
是不同的野兽,前者必须与CSSOM当前状态保持一致(它将在获取时触发一个recalc),后者并不关心CSSOM。@kaido-这是真的,但基本点保持不变。(但是我更新了第一个堆栈片段,在
getComputedStyle
中调用
getOwnPropertyDescriptor
,而不是[我在早期版本中这样做了,然后在编辑时弄糟了]。)“它只是一个getter…”在Chrome和相关浏览器上,它声称是一个数据属性。它存在::-)正如@T.J.Crowder所说,我发现它只是一个字段而不是一个方法,所以我很好奇@박창대 - 是的,这是Chrome(ium)的一个怪癖,而且它是骗人的。Firefox和Legacy Edge将其作为原型上的访问器进行报告,这似乎更现实一些。:-)