• 0

  • 0

JavaScript:对象属性的特性

2星期前

对象和属性

JS中,对象是键值对的集合。这些值是对象的属性,它可以是一个基本类型或对象,也可以是方法(method)。

比如:

const Person = {
  name: 'Brynn',
  greet: function () {
    console.log('Hello I am', this.name)
  },
}
复制代码

上面这个对象有一个name基本类型,和一个greet方法。
用上面这种定义方法是最简单的,称为用字面量定义。

除此之外,还可以用Object.defineProperty()配置一个属性,用Object.getOwnPropertyDescripter()查询配置具体情况。

所以,上面的代码可以写成:

const Person = {}
Object.defineProperty(Person, 'name', {
  value: 'Brynn',
  writable: true,
  enumerable: true,
  configurable: true,
})
Object.defineProperty(Person, 'greet', {
  value: function () {
    console.log('Hello I am', this.name)
  },
  writable: true,
  enumerable: true,
  configurable: true,
})
复制代码

特性

Object.defineProperty中出现了一些属性(property)的特性(attribute),这些特性如下:

  • value: 属性的值
  • writable: 是否可修改属性的value
  • enumerable: 是否可枚举(只有可枚举的属性才能同构Object.keys(target)以及for in获取,可枚举和不可枚举的都可以通过Object.getOwnPropertyNames(target)获取)
  • configurable:是否可修改属性的attribute,只有可配置属性的才能被delete删除
  • set: 写入属性时调用的函数(使用Brynn.name = 'Boolean'就会调用set函数)
  • get:获取属性时调用的函数(使用console.log(Brynn.name)就会调用get函数)

这些特性不能同时全部存在于一个属性上,根据这一点的不同,又将属性分为数据属性访问器属性

  • 数据属性:有value/writable/enumerable/configurable四个特性
  • 访问器属性: 有set/get/enumerable/configurable四个特性

Object.defineProperty()

set和get的用法如下

const Person = {
  _name: 'abc',
}
// Object.defineProperty(Person, 'name', {
//   value: 'Brynn',
//   writable: true,
//   enumerable: true,
//   configurable: true,
// })
Object.defineProperty(Person, 'name', {
  set: function (value) {
    if (value.match(/[bB]rynn/)) this._name = value
  },
  get: function () {
    return this._name
  },
  enumerable: true,
  configurable: true,
})
console.log('setter属性', Object.getOwnPropertyDescriptor(Person, 'name'))
复制代码

Object.defineProperty有默认值:

{
 set: undefined,
 get:undefined,
 writable:false,
 enumerable:false,
 configurable:false
}
复制代码

当使用字面量直接定义时,这些特性的默认值不同:

{
 writable:true,
 enumerable:true,
 configurable:true
}
复制代码

getter和setter

getter/setter很类似于Object.defineProperty()的访问器属性

Getter/setter

let Person = {
  _name: 'abc',
  set name(value) {
    console.log(' setter函数里面调用this', this)
    if (value.match(/[bB]rynn/)) this._name = value
  },
  get name() {
    console.log(' getter里面调用this', this)
    return this._name
  },
}
console.log('使用setter定义的name属性', Object.getOwnPropertyDescriptor(Person, 'name'))
console.log('Person对象(person)', Person)
console.log('Person对象自己的属性(Object.getOwnPropertyNames):', Object.getOwnPropertyNames(Person))
复制代码

Object.defineProperty

let Person = {
  _name: 'abc',
}

Object.defineProperty(Person, 'name', {
  set: function (value) {
    console.log('set函数里面调用this', this)
    if (value.match(/[bB]rynn/)) this._name = value
  },
  get: function () {
    console.log(' getter里面调用this', this)
    return this._name
  },
  // enumerable: true,
  // configurable: true,
})
console.log('使用setter定义的name属性', Object.getOwnPropertyDescriptor(Person, 'name'))
console.log('Person对象(person)', Person)
console.log('Person对象自己的属性(Object.getOwnPropertyNames):', Object.getOwnPropertyNames(Person))
复制代码

区别是

  1. 用defineProperty添加属性更灵活,可以动态添加
  2. 特性的默认值不同,defineProperty的默认值是false,setter/getter的默认值是true

自身属性和原型属性

对象属性做遍历的时候,会用到的方法有for infor of

  • for in:遍历自身和原型链上的所有可枚举属性,返回的是键
  • for
免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

java

0

相关文章推荐

未登录头像

暂无评论