关于javascript:深入理解js对象

定义对象

两种形式定义对象

let person = new Object()
obj.name = '蛙人'
obj.age = 23
obj.sex = 'male'
obj.getAge = function() {
    return this.age
}

下面的例子创立了一个person对象实例,并为它增加了属性及办法,在晚期js开发人员常常应用这种形式,然而当初对象字面量成了首先形式,看一下字面量定义对象。

let person = {
    name: '蛙人',
    age: 23,
    sex: 'male',
    getAge() {
        return this.age
    }
}

能够看到下面这种应用字面量的形式定义对象更加简洁明了,字面量的形式跟第一种定义形式是一样的。

属性类型

在说数据属性时,咱们先来讲一下js里的外部属性, 在Es5版本中,在定义只有外部才用的个性attribute时,形容了属性property的各种
特色, 定义这些个性是为了实现js引擎用的,因而在js里无法访问外部属性,外部属性是两个中括号括起来的例如 [[Enumerable]]

数据属性

数据属性蕴含一个数据值的地位,在这个地位能够进行读取和写入值,那么这就是数据属性形容对象。

  • [[Configuralbe]] : 示意是否能够delete删除该属性,是否能在对象上定义其它属性,是否能批改属性值,默认返回true。
  • [[Enumerable]] :示意是否能够枚举该属性for in, 默认返回true。
  • [[Writeable]] : 示意是否能够读写改属性,默认返回true。
  • [[Value]] : 示意属性值的地位,每次读取属性的时,从这个[[Value]]外部属性返回值,写入属性值的时候,把值保留在这个地位,默认返回undefined,这也就是咱们所读取对象上不存在的属性时,返回undefined的起因。

实践讲完了,那么间接上代码一把梭


[[Value]]

let person = {
    name: '蛙人'
}

下面example中定义属性name,为它的值默认 “蛙人” 也就是说,在外部属性 [[Value]] 中保留了该值, 从这点咱们明确,只有是对象中批改或写入值,都会触发外部属性 [[Value]]

批改属性形容对象

如果要批改数据属性的形容对象,应用Es5中Object.defineProperty()办法,这个办法接管三个参数,指标对象、要拜访的属性、属性的形容对象,形容对象必须是: configurable、enumerable,writeable、value, 设置其中一或多属性,能够批改对应的形容属性值。

let person = {}
Object.defineProperty(person, 'name', {
    writeable: false, // 不能写入
        value: '你没有permission'
})

console.log(person.name) // 你没有permission
person.name = "蛙人"
console.log(person.name) // 你没有permission

在下面example中,咱们设置了person对象形容对象为只读不可写,又为它设置了value属性,所以不论它怎么读取都返回你没有permission,怎么写都不能够,须要留神的是下面代码在严格模式下会抛出谬误,在非严格模式下赋值操作则会疏忽而且更为重要的一点,Object.defineProperty第三个参数必须写,不然code报错

拜访器属性

数据拜访器属性不蕴含数据值, 他们蕴含一对 getter和setter函数 (这两个函数不是必须的 可选)。

在读取拜访器属性时,会调用getter函数,在写入拜访器属性时,会调用setter函数,函数接管一个参数这个参数就是写入的值。

  • [[get]]:在读取属性时调用的函数,默认返回undefined
  • [[set]]:在写入属性时调用的函数,默认返回undefined

拜访器属性不能间接定义,应用Object.defineProperty(),请看上面 example

let person = {
    _age: 23,
    name: '蛙人'
}

Object.defineProperty(person, "age", {
    get() {
        return this._age
    },
    set(val) {
        this._age = val
    }
})
person.age = 24

下面example中,写入age属性就会触发拜访器对象里的set函数,从而从新赋值,而后触发get办法,返回该属性值,下面应用了_age这种定义形式示意为罕用的mark,示意只能通过对象办法拜访的属性, 不要间接写在get函数返回里返回本身 如:this.age = xxx 这样会造成堆栈溢出

定义多个形容属性

Es5版本中还有一个Api办法是定义多个对象写入形容属性, 该办法接管2个参数,指标对象、属性值,请看下列example

let person = {}
Object.defineProperties(person, {
    _age: {
        value: 23
    },
    name: {
        value: "蛙人"
    },
    age:{
        get() {
            return this._age
        },
        set(val) {
            this._age = val;
        }
    }
})

下面example与 上一个example都是同样的代码成果,只不过定义形式不同,该办法不常常应用,大家晓得就好。

获取对象的形容属性

Es5版本中定义了一个Api办法能够查看以后对象的形容属性,Object.getOwnPropertyDescriptor(), 该办法接管2个参数,指标对象、属性值

let person = {
     age: 23
}
let descriptor = Object.getOwnPropertyDescriptor(person, "age")
console.log(descriptor.writable)  // true
console.log(descriptor) // {"value":23,"writable":true,"enumerable":true,"configurable":true}

下面example中能够分明的看见以后的对象属性的形容对象,这样在呈现bug的时候,咱们也能够查看以后的形容属性是否能够更改,疾速定位bug,在js中能够针对任何对象应用Object.getOwnPropertyDescriptor(), 包含BOM和DOM对象,兼容IE9 +、Firefox4+、Safari5+、Opera12+、Chrome。


如果该文章对你有帮忙,请点个赞吧

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理