JS 基础: Get Check Object Properties 获取和检查对象属性

news/2024/7/19 13:19:05 标签: js, javascript, object, property

JS 基础: Get & Check Object Properties 获取和检查对象属性

文章目录

  • JS 基础: Get & Check Object Properties 获取和检查对象属性
    • 简介
    • 参考
  • 正文
    • 获取属性
      • `Object.keys(obj)`
      • `Object.getOwnPropertyNames(obj)`
      • `Object.getOwnPropertySymbols(obj)`
      • `getOwnProperties` & `getOwnEnumerableProperties`
    • 检查属性存在
      • `Object.prototype.hasOwnProperty(prop)`
      • `in` 关键字
      • `hasInheritProperty`
  • 结语

简介

JS 中的对象可说是千变万化,对象的属性可能随时都在改变,那么我们要如何动态的获取对象的所有属性呢?

本篇就将从 Object 的各种静态方法来切入,透过使用 Object.keysObject.getOwnPropertyNamesObject.getOwnPropertySymbolsObject.prototype.hasOwnPropertyin 等方法和关键字来获取和检查对象的属性。

参考

Object.keys()-MDNhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Object.getOwnPropertyNames()-MDNhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
Object.getOwnPropertySymbols()-MDNhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols
Object.prototype.hasOwnProperty()-MDNhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
in-MDNhttps://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/in

正文

正文部分分成两个模块,一个是获取对象的属性,一个是检查对象是否拥有属性(自己的属性或是继承的属性)

获取属性

接下来我们要透过下列几个方法来获取对象的属性:

  • Object.keys(obj)
  • Object.getOwnPropertyNames(obj)
  • Object.getOwnPropertySymbols(obj)

Object.keys(obj)

第一个方法是 Object.keys(obj),它可以获取所有自有且 enumerable: true 的属性,示例如下:

js">const object = { a: 1, b: 2, c: 3 }
console.log(Object.keys(object))
Object.defineProperty(object, 'c', { enumerable: false })
console.log(Object.keys(object))
[ 'a', 'b', 'c' ]
[ 'a', 'b' ]

我们可以看到,c 被设置成 enumerable: false 之后就不会再被 Object.keys 所发现

Object.getOwnPropertyNames(obj)

第二个方法 Object.getOwnPropertyNames(obj)Object.keys(obj) 几乎一样,唯一不同的是 enumerable: false 的属性也会被找到,接着上面的例子:

js">const object = { a: 1, b: 2, c: 3 }
console.log(Object.getOwnPropertyNames(object))
Object.defineProperty(object, 'c', { enumerable: false })
console.log(Object.getOwnPropertyNames(object))
[ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]

看到了即使 c 被设为 enumerable: false,还是被 Object.getOwnPropertyNames 找出来了

Object.getOwnPropertySymbols(obj)

现在还存在一个问题是,ES6 新增了一个基础类型 Symbol,同时它是除了字符串(String)外能够作为键的唯一选择,使用如下:

js">const symbolA = Symbol('a')
const object = { a: 1, b: 2, c: 3, [symbolA]: 4 }
console.log(object)
console.log(Object.getOwnPropertyNames(object))
{ a: 1, b: 2, c: 3, [Symbol(a)]: 4 }
[ 'a', 'b', 'c' ]

好像有点问题,Object.getOwnPropertyNames 找不到以 Symbol 类型的键,这时候即必须使用 Object.getOwnPropertySymbols;并且与 Object.getOwnPropertyNames 一样,即使属性 enumerable: true 也会被找出来

js">const symbolA = Symbol('a')
const symbolB = Symbol('b')
const object = { a: 1, b: 2, c: 3, [symbolA]: 4, [symbolB]: 5 }
Object.defineProperty(object, 'c', { enumerable: false })
Object.defineProperty(object, symbolB, { enumerable: false })
console.log(object)
console.log(Object.keys(object))
console.log(Object.getOwnPropertyNames(object))
console.log(Object.getOwnPropertySymbols(object))
{ a: 1, b: 2, [Symbol(a)]: 4 }
[ 'a', 'b' ]
[ 'a', 'b', 'c' ]
[ Symbol(a), Symbol(b) ]

getOwnProperties & getOwnEnumerableProperties

根据上述的方法,我们可以抽象出两个个获得所有属性名的方法,一个获取所有自有属性(getOwnProperties);一个获取所有可枚举(enumerable: false)的自有属性(getOwnEnumerableProperties)

js">// 获取所有属性
function getOwnProperties (obj) {
  const keys = Object.getOwnPropertyNames(obj)
  const symbols = Object.getOwnPropertySymbols(obj)
  return [...keys, ...symbols]
}

// 获取所有可枚举自有属性
function getOwnEnumerableProperties (obj) {
  const props = getOwnProperties(obj)
  const enumerableProps = props.filter(prop => Object.getOwnPropertyDescriptor(obj, prop).enumerable)
  return enumerableProps
}

const symbolA = Symbol('a')
const symbolB = Symbol('b')
const object = { a: 1, b: 2, c: 3, [symbolA]: 4, [symbolB]: 5 }
Object.defineProperty(object, 'c', { enumerable: false })
Object.defineProperty(object, symbolB, { enumerable: false })
console.log(getOwnProperties(object))
console.log(getOwnEnumerableProperties(object))
[ 'a', 'b', 'c', Symbol(a), Symbol(b) ]
[ 'a', 'b', Symbol(a) ]

检查属性存在

检查属性的方法有两种:

  • Object.prototype.hasOwnProperty:检查对象自有属性是否包含指定属性
  • in 关键字:检查原型链上是否包含指定属性

Object.prototype.hasOwnProperty(prop)

js">const nums = [ -1, -2, -3 ]
console.log('----- check nums -----')
console.log(getOwnProperties(nums))
console.log(`nums.hasOwnProperty(0): ${nums.hasOwnProperty(0)}`)
console.log(`nums.hasOwnProperty(1): ${nums.hasOwnProperty(1)}`)
console.log(`nums.hasOwnProperty(2): ${nums.hasOwnProperty(2)}`)
console.log(`nums.hasOwnProperty(3): ${nums.hasOwnProperty(3)}`)
console.log(`nums.hasOwnProperty(-1): ${nums.hasOwnProperty(-1)}`)
console.log(`nums.hasOwnProperty('length'): ${nums.hasOwnProperty('length')}`)
console.log(`nums.hasOwnProperty('toString'): ${nums.hasOwnProperty('toString')}`)

const sa = Symbol('a')
const sb = Symbol('b')
const object = { a: 1, b: 2, [sa]: 3, [sb]: 4 }
Object.defineProperty(object, 'b', { enumerable: false })
Object.defineProperty(object, sb, { enumerable: false })
console.log('----- check object -----')
console.log(getOwnProperties(object))
console.log(getOwnEnumerableProperties(object))
console.log(`object.hasOwnProperty('a'): ${object.hasOwnProperty('a')}`)
console.log(`object.hasOwnProperty('b'): ${object.hasOwnProperty('b')}`)
console.log(`object.hasOwnProperty(sa): ${object.hasOwnProperty(sa)}`)
console.log(`object.hasOwnProperty(sb): ${object.hasOwnProperty(sb)}`)
console.log(`object.hasOwnProperty('toString'): ${object.hasOwnProperty('toString')}`)
----- check nums -----
[ '0', '1', '2', 'length' ]
nums.hasOwnProperty(0): true
nums.hasOwnProperty(1): true
nums.hasOwnProperty(2): true
nums.hasOwnProperty(3): false
nums.hasOwnProperty(-1): false
nums.hasOwnProperty('length'): true
nums.hasOwnProperty('toString'): false
----- check object -----
[ 'a', 'b', Symbol(a), Symbol(b) ]
[ 'a', Symbol(a) ]
object.hasOwnProperty('a'): true
object.hasOwnProperty('b'): true
object.hasOwnProperty(sa): true
object.hasOwnProperty(sb): true
object.hasOwnProperty('toString'): false

我们可以看到不管 enumerable 的描述符是 true 还是 false,只要是自有属性 hasOwnProperty 都会返回 true;

对于数组来说的属性名是下标而不是属性值;

toString 等从原型继承过来的属性则为 false。

in 关键字

js">const nums = [ -1, -2, -3 ]
console.log('----- check nums -----')
console.log(getOwnProperties(nums))
console.log(`0 in nums: ${0 in nums}`)
console.log(`1 in nums: ${1 in nums}`)
console.log(`2 in nums: ${2 in nums}`)
console.log(`3 in nums: ${3 in nums}`)
console.log(`-1 in nums: ${-1 in nums}`)
console.log(`'length' in nums: ${'length' in nums}`)
console.log(`'toString' in nums: ${'toString' in nums}`)

const sa = Symbol('a')
const sb = Symbol('b')
const object = { a: 1, b: 2, [sa]: 3, [sb]: 4 }
Object.defineProperty(object, 'b', { enumerable: false })
Object.defineProperty(object, sb, { enumerable: false })
console.log('----- check object -----')
console.log(getOwnProperties(object))
console.log(getOwnEnumerableProperties(object))
console.log(`'a' in object: ${'a' in object}`)
console.log(`'b' in object: ${'b' in object}`)
console.log(`sa in object: ${sa in object}`)
console.log(`sb in object: ${sb in object}`)
console.log(`'toString' in object: ${'toString' in object}`)
----- check nums -----
[ '0', '1', '2', 'length' ]
0 in nums: true
1 in nums: true
2 in nums: true
3 in nums: false
-1 in nums: false
'length' in nums: true
'toString' in nums: true
----- check object -----
[ 'a', 'b', Symbol(a), Symbol(b) ]
[ 'a', Symbol(a) ]
'a' in object: true
'b' in object: true
sa in object: true
sb in object: true
'toString' in object: true

Object.prototype.hasOwnProperty 不同的是从原型链上继承下来的属性(如 toString),在 in 操作符检查之下结果也是 true

hasInheritProperty

基于 Object.prototype.hasOwnPropertyin 两种判断方式,我们就可以写出一个检查是否为继承属性(hasInheritProperty)的方法

js">function hasInheritProperty (obj, prop) {
  return prop in obj && !obj.hasOwnProperty(prop)
}

const sa = Symbol('a')
const object = { a: 1, [sa]: 2 }
console.log(hasInheritProperty(object, 'a'))
console.log(hasInheritProperty(object, sa))
console.log(hasInheritProperty(object, 'toString'))
js">false
false
true

结语

本篇介绍了如何在 JS 中获取对象属性,以及检查对象是否包含属性(自有或继承的),最后自己实现了三个新的方法 getOwnProperties 获取所有自有属性getOwnEnumerableProperties 获取所有可枚举自有属性hasInheritProperty 检查是否为继承属性,供大家参考。


http://www.niftyadmin.cn/n/735455.html

相关文章

Linux基础(四)SSH SCP文件传输

蓝色 紫色 红色 SSH   (Secure Shell) 参考链接:SSH简介及两种远程登录的方法 Git 官方手册 - 4.3 服务器上的 Git - 生成 SSH 公钥 简要介绍 SSH是建立在 应用层基础上 的专为 远程登录会话 和其他网络服务提供安全性的可靠安全协议。SSH 协议可以有效防止远…

024 IDEA不能新建spring下的配置文件xml

这个问题以前就遇到过,一直懒得解决,现在必须要用了,解决了一下,发现网上的解决方式果然不错。 1.现象 2.解决方式 需要添加一下spring context的依赖即可

C 基础: Enum 枚举类型

C 基础: Enum 枚举类型 文章目录C 基础: Enum 枚举类型简介参考正文枚举类型语法非连续值结语简介 今天来说说 C 语言里面的枚举类型。在程序中常常会需要对一些现实生活的属性进行枚举,如性别通常不是男就是女、一周七天、进程状态定义等。 第一种做法我们可以透…

Linux服务器上配置GitGithub

配置账户信息 参考连接:本地Git配置绑定远程Github账户 git config --global user.name "Kikihqq" # 这里是 github 注册的账号(用户名) git config --global user.email "HuiqingZhoutlook.com" # github 注册的邮箱 …

Linux基础(五)Git

蓝色 紫色 红色 Git Git版本控制与github使用 基本概念 工作区:你当前存放代码、文件的 文件夹 。所有分支的修改都是在这个工作区里的,即你的工作区会包含所有branch。 暂存区:数据暂时存放的区域,类似于工作区写入版本库前…

C 进阶: Var Args 可变参数

C 进阶: Var Args 可变参数 文章目录C 进阶: Var Args 可变参数简介参考正文固定参数函数标准库 简介 学习过 C 语言肯定写过 printf("Hello Wolrd!"); 这句,其中使用的 printf 便是一种接受可变长参数的函数。我们都知道只要在第一个参数的字符串里面加…

近期图像处理相关问题记录

plt.imshow()显示不出图片 在之后添加 plt.show() import matplotlib.pyplot as plt plt.imshow(predicted_boxes[:,:,::-1]) plt.show()更换颜色通道顺序 图像通道转换——从np.ndarray的[w, h, c]转为Tensor的[c, w, h] # img in BlueGreenRed (opencv style) -> matp…

链接服务器 (null) 的 OLE DB 访问接口 SQLNCLI11 指示该对象没有列,或当前用户没有访问该对象的权限。...

原文:链接服务器 "(null)" 的 OLE DB 访问接口 "SQLNCLI11" 指示该对象没有列,或当前用户没有访问该对象的权限。 SELECT * FROMOPENROWSET(SQLOLEDB, server.;uidsa;pwdsdty-cc, exec DBMobileBJ.dbo.Do_CallProcess_Jcmx_Report ); GO ---改为…