javaScript支持多种编程范式,包括函数式编程和面向对象编程,javaScript的对象被设计成一组属性的无序集合,由key和value组成。
创建对象的两种方式
- 早期使用创建对象方式最多的是使用Object类,使用new关键字来创建一个对象,这是因为早期很多javaScript开发者是从java过来的,他们也更习惯于java中通过new的方式创建一个对象。
let obj = new Object
obj.name = '小明'
obj.age = 18
- 后来很多开发者为了方便,都直接通过字面量的形式来创建对象,这种形式看起来更加的简洁,并且对象和属性之间的内聚性也更强。
let obj = {
name: '小明',
age: 18
}
对属性操作的控制
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
语法
Object.defineProperty(obj, prop, descriptor)
参数
obj:要定义的属性
prop:要定义或修改的属性名称或Symbol
descriptor:要定义或修改的属性描述符
返回值
被传递给函数的对象,也就是obj
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。一个属性描述符只能是这两者其中之一;不能同时是两者。
如果一个描述符不具有 value、writable、get 和 set 中的任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有 value 或 writable 和 get 或 set 键,则会产生一个异常。
数据数据描述符有如下四个特性:
1 .configurable
表示属性是否可以通过delete删除属性,是否可以修改它的特性,或者是否可以将它修改为存取属性描述符;
- 当我们直接在一个对象上定义某个属性时,这个属性的[[Configurable]]为true;
- 当我们通过属性描述符定义一个属性时,这个属性的[[Configurable]]默认为false;
- 为false时 ,如果writable为true可修改其为false,如果writable为false,不能修改其为true
2 .Enumerable
当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中,表示属性是否可以通过for-in或者Object.keys()返回该属性;
- 当我们直接在一个对象上定义某个属性时,这个属性的Enumerable为true;
- 当我们通过属性描述符定义一个属性时,这个属性的Enumerable默认为false;
3. Writable
表示是否可以修改属性的值
- 当我们直接在一个对象上定义某个属性时,这个属性的[[Writable]]为true;
- 当我们通过属性描述符定义一个属性时,这个属性的[[Writable]]默认为false;
4. value
属性的value值,读取属性时会返回该值,修改属性时,会对其进行修改
- 默认情况下这个值是undefined;
存取属性描述符有如下四个特性:
1. configurable
同数据描述符
2. Enumerable
同数据描述符
3. get
获取属性时会执行的函数。默认为undefined
3. set
设置属性时会执行的函数。默认为undefined
描述符默认值汇总
- 拥有布尔值的键 configurable、enumerable 和 writable 的默认值都是 false。
- 属性值和函数的键 value、get 和 set 字段的默认值为 undefined。
添加多个属性和默认值
考虑特性被赋予的默认特性值非常重要,通常,使用点运算符和 Object.defineProperty() 为对象的属性赋值时,数据描述符中的属性默认值是不同的,如下例所示。
var o = {};
o.a = 1;
// 等同于:
Object.defineProperty(o, "a", {
value: 1,
writable: true,
configurable: true,
enumerable: true
});
// 另一方面,
Object.defineProperty(o, "a", { value : 1 });
// 等同于:
Object.defineProperty(o, "a", {
value: 1,
writable: false,
configurable: false,
enumerable: false
});
同时定义多个属性
Object.defineProperties() 方法直接在一个对象上定义 多个 新的属性或修改现有属性,并且返回该对象
Object.defineProperties(obj, {
name: {
configurable: true,
enumerable: true,
writable: true,
value: "why"
},
age: {
configurable: true,
enumerable: true,
get: function() {
return this._age
},
set: function(value) {
this._age = value
}
}
})
对象方法补充
- getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
语法
Object.getOwnPropertyDescriptor(obj, prop)
参数
obj:需要查找的目标对象
prop:目标对象内属性名称
例
o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d {
// configurable: true,
// enumerable: true,
// value: 42,
// writable: true
// }
- getOwnPropertyDescriptors
Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。
语法
Object.getOwnPropertyDescriptors(obj)
参数
obj:任意对象
返回值
所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
- Object.preventExtensions()
Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。
语法
Object.preventExtensions(obj)
参数
obj:将要变得不可扩展的对象
返回值
已经不可扩展的对象。
- Object.seal()
Object.seal() 方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
语法
Object.seal(obj)
参数
obj:将要被密封的对象。
返回值
被密封的对象。
- Object.freeze()
Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象。
语法
Object.seal(obj)
参数
obj:要被冻结的对象。
返回值
被冻结的对象。