以下表达式的计算结果均为TRUE:

'z-index' in getComputedStyle(document.body) // true
Reflect.has(getComputedStyle(document.body), 'z-index')  // true

事实上,下面的求值结果也为True,这表明‘z-index’是相应CSSStyleClaimation对象的own属性的名称:

getComputedStyle(document.body).hasOwnProperty('z-index')  // true
Object.hasOwn(getComputedStyle(document.body), 'z-index')  // true

但是,this的计算结果为False

Reflect.ownKeys(getComputedStyle(document.body)).includes('z-index')  // false

怎么可能Object.hasOwn(x, y)的判断结果为真,而Reflect.ownKeys(x).includes(y)的判断结果为假呢?这没有任何意义.

还要注意的是,这种情况并不是因为getComputedStyle(Document.Body)是一个只读的、经过计算的CSSStyleClaimation对象.从HTMLElement的Style属性检索到的CSSStyleClaimation对象不是只读的,但同样的情况也会发生:

Object.hasOwn(document.body.style, 'z-index') // true
Reflect.ownKeys(document.body.style).includes('z-index') // false

MDN称(https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle)

可以使用getPropertyValue(PropName)API或通过直接索引对象(如obj[‘z-index’]或obj.zIndex)来访问css属性值.

我理解允许访问obj['z-index']的值的convenience.我想知道的是,在给定ECMASSCRIPT语言的规则的情况下,Object.has Own(x,y)和Reflect.ownKeys(X).Includes(Y)之间产生的真值差异是如何可能的.

编辑:我发现了另一个堆栈溢出问题,它提出了完全相同的问题(how does it work element.style["background-color"]),但没有得到明确的答案.

推荐答案

你已经正确地分析了情况.

然而,没有什么是不允许的,您也可以使用代理自己创建这样的情况.例如:

function createCaseInsensitiveObject() {
  return new Proxy({}, {
    getOwnPropertyDescriptor (target, property) {
      return Reflect.getOwnPropertyDescriptor(target, property.toLowerCase())
    },

    defineProperty (target, property, descriptor) {
      return Reflect.defineProperty(target, property.toLowerCase(), descriptor)
    },

    has (target, property) {
      return Reflect.has(target, property.toLowerCase())
    },

    get (target, property) {
      return Reflect.get(target, property.toLowerCase())
    },

    set (target, property, value) {
      return Reflect.set(target, property.toLowerCase(), value)
    },

    deleteProperty (target, property) {
      return Reflect.deleteProperty(target, property.toLowerCase())
    }

    // Note: ownKeys is NOT overridden as it
    // would be impractical to return all permutations
    // of casing like hElLo etc.
  })
}

const obj = createCaseInsensitiveObject()
obj.Hello = 123
console.log(obj.HELLO) // 123
console.log(obj.hElLo) // 123
console.log('hElLo' in obj) // true
console.log(Reflect.ownKeys(obj)) // ['hello']
console.log(Reflect.ownKeys(obj).includes('hElLo')) // false

这解释了差异:[[Has]] internal方法返回true[[GetOwnProperty]] internal方法返回一个有效的描述符,但是[[OwnPropertyKeys]] internal方法返回一个不包含该键的array.

内部函数[[OwnPropertyKeys]]的使用方式不应该是获取返回的数组并判断它是否包含一些已知的键.为了发现密钥,需要对其进行迭代.含义:实际上,您会调用Object.hasOwn来判断某些特定属性是否存在,并使用Object.keys(或者,如果包含不可枚举的属性,则使用Object.getOwnPropertyNames)来迭代属性.在这种情况下,您会让CSSStyleDeclaration表现得很好(每个真实的属性只返回一次,但当直接访问您已经知道其名称的属性时,两种编写属性的方式都被接受).

Javascript相关问答推荐

主要内部的ExtJS多个子应用程序

具有相同参数的JS类

使用TMS Web Core中的HTML模板中的参数调用过程

调用removeEvents不起作用

通过嵌套模型对象进行Mongoose搜索

扫描qr code后出错whatter—web.js

使用useEffect,axios和useParams进行react测试

将现场录音发送到后端

Regex结果包含额外的match/group,只带一个返回

Prisma具有至少一个值的多对多关系

使用Google API无法进行Web抓取

Eval vs函数()返回语义

更新动态数据中对象或数组中的所有值字符串

是否可以在不更改组件标识的情况下换出Reaction组件定义(以维护状态/引用等)?如果是这样的话,是如何做到的呢?

我的NavLink活动类在REACT-ROUTER-V6中出现问题

为什么我的SoupRequest";被重置为初始值,以及如何修复它?

如何在加载页面时使锚定标记成为焦点

KeyboardEvent:检测到键具有打印的表示形式

如何缩小函数中联合返回类型的范围

使用导航时,路径的所有子组件都必须是路径