一、理解对象
let person = {
name: "limengxiao",
age: "30",
job: "前端开发工程师"
sayName() {
console.log("我的名字叫" + this.name);
}
}
这是通常的对象自变量定义对象的方法。该对象中每个属性都有自己的特征,而这些特征决定了,他们在javascript中的行为。
1.1、属性的类型
ECMA-262使用一些内部特性来描述属性的特征。这些特性是由为JavaScript实现引擎的规范定义的。因此,开发者不能在JavaScript中直接访问这些特性。为了将某个特性标识为内部特性,规范会用两个中括号把特性的名称括起来,比如[[Enumerable]]。
属性氛围两种:数据属性和访问器属性。
1、数据属性
数据属性包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。
数据属性有四个特性描述它们的行为:
- [[Configurable]]
- [[Enumerable]]
- [[Writable]]
- [[Value]]
要修改属性的默认特性,必须使用Object.defineProperty。这个方法接受三个参数:要给其添加属性的对象、属性的名称和一个描述符对象。例如:
let person = {}
Object.defineProperty(person, name, {
writable: false,
value: "limengxiao"
})
console.log(person.name) //limengxiao
person.name = "anthor"
console.log(person.name) //limengxiao
只读的属性,在非严格模式下尝试给这个属性重新赋值会被忽略。在严格模式下,尝试修改只读属性的值会抛出错误。
PS:一个对象属性被定义成不可配置的之后,就不能变成可配置的了,在严格模式下也会抛错。
多数情况下,可能都不需要Object.defineProperty()提供的这些强大的设置,但要理解JavaScript对象,就要理解这些概念。
2、访问器属性
访问器属性不包含数据值。相反它包含一个获取(getter)函数,和设置(setter)函数,不过这两个函数不是必须的。
访问器属性有四个特性描述他们的行为:
- [[Configurable]]
- [[Enumerable]]
- [[Get]]
- [[Set]]
访问器属性是不能并直接定义的,必须通过Object.defineProperty()定义。
// 定一个对象包含伪私有成员year_和公共成员edition
let book = {
year_: 2017,
edition: 1
}
Object.defineProperty(book, "year", {
get() {
return this.year_;
}
set(newValue) {
if(newValue > 2017) {
this.year_ = newValue;
this.edition = newValue - 2017;
}
}
})
book.year = 2018;
console.log(book.edition) // 2
解析:year中的下划线常用来表示该属性并不希望在对象方法的外部被访问。另一个属性year被定义为一个访问器属性,其中获取函数简单地返回year的值,而设置函数会做一些计算以决定正确的版本(edition)