属性
数据属性
对象的属性可分为 数据属性 和 访问器 属性。
ES5 中新增了属性描述符用来描述对象中的数据属性。
var obj = {
count: 6
};
Object.getOwnPropertyDescriptor(obj, 'count');
// {
// value: 6,
// writable: true,
// enumerable: true,
// configurable: true
// }
默认情况下,3 个描述符都为 true。
可写性 writable
writable 决定是否可以修改属性值,如果为 false,将不能修改。
- 在普通模式下,尝试修改会静默失败
- 在严格模式下,尝试修改会抛出错误
var obj = {};
Object.defineProperty(obj, 'a', {
value: 6,
writable: false, // 不可写
} );
可配置性 configurable
configurable 表示是否可以修改属性的描述符。
如果 configurable 被设置成 false 了,那么就不能再修改这 3 个描述符,尝试修改会报错,同时,执行 delete 操作也会静默失败。
当然,除了 writable,它比较特殊。
如果 configurable 变成 false 后,writable 可以由 true 变成 false,但是不能由 false 变成 true。
所以,configurable 是单向操作,一旦变为 false,就不能再改成 true。
可枚举性 enumerable
它控制着一个属性是否能在特定的对象-属性枚举操作中(属性被迭代时)出现,比如:
for in 循环
Object.keys 方法
JSON.stringify 方法
设置为 false 就不会出现在上述枚举和方法中,但是依然是可以通过对象访问的。
propertyIsEnumerable 方法可用于判断一个属性是否直接存在于对象上,并使是可枚举的。
访问器属性
访问器属性包含两个函数:getter 和 setter,分别在读取和设置属性值的时候调用。
除此之外,还包括 configurable 和 enumerable。
注意:同时定义数据属性和访问器属性会报错:Invalid property descriptor. Cannot both specify accessors and a value or writable attribute。
直接定义:
var obj = {
get name() {
return 'test';
}
};
通过方法定义:
Object.defineProperty(
obj,
"age",
{
get: function(){
return 18;
},
}
);
不可变性
下面创建的都是 浅 不可变性,只对 对象 的直接属性起作用,如果属性是对其他对象的引用,那被引用的属性不受影响。
对象常量
通过使用 writable 和 configurable 可以使对象的属性不能修改和删除。
const CONSTANTS = {};
Object.defineProperty(CONSTANTS, 'PI', {
value: 3.14,
writable: false,
configurable: false,
});
防止扩展
禁止对象添加新的属性,如果添加会静默失败,严格模式下报错。
const obj = {
value: 2
};
Object.preventExtensions( obj );
obj.name = 'test';
obj.name; // console: undefined
封印
Object.seal 方法接收一个对象,它对这个对象做了两件事情:
- 在对象调用
Object.preventExtensions 方法,禁止其扩展
- 将对象现有属性的
configurable 设置为 true,所以,不能配置和删除属性
但是,如说属性的 writable 为 true,就已然可以修改属性值。
冻结
Object.freeze 方法,相当于在 seal 的基础上,将属性的 writable 设置为 false。
对象的属性不能配置、删除,也不能修改。
属性存在性
in 操作符
in 操作符会检查属性是否存在于对象或者其原型链的对象上。
hasOwnProperty
hasOwnProperty 方法也可以判断一个对象是否有某个属性,但是不会检查原型链。
一般情况下,可以通过普通对象直接访问 hasOwnProperty 方法,但是更好的方式是:
Object.prototype.hasOwnProperty.call(obj, "name")
这样可以防止 obj 对象没有链接到 Object.prototype,不能访问 hasOwnProperty 方法。
对象的方法汇总
keys
返回一个所有可枚举属性的数组,不包括原型链上的属性。
Object.keys(obj);
getOwnPropertyNames
返回一个所有属性的数组,不论是否可以枚举。
Object.getOwnPropertyNames(obj);
propertyIsEnumerable
判断一个属性是否直接存在于对象,并且是可枚举的。
obj.propertyIsEnumerable('name');
hasOwnProperty
判断对象是否直接拥有属性。
Object.prototype.hasOwnProperty.call(obj, "name");
defineProperty
定义单个数据属性或访问器属性。
Object.defineProperty(obj, "name", {
value: 'tom',
writable: false,
configurable: true,
enumerable: true
} );
defineProperties
定义多个数据属性或访问器属性。
Object.defineProperty(obj, {
name: {
value: 'tom',
writable: false,
},
age: {
get() {
return 18;
}
}
});
getOwnPropertyDescriptor
获取某个属性的属性描述符。
Object.getOwnPropertyDescriptor(obj, name);
getOwnPropertyDescriptors
获取对象所有属性的属性描述符。
Object.getOwnPropertyDescriptors(obj);
is
比较两个值是否严格相等。
Object.is('test', 'test') // true
Object.is({}, {}) // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
+0 === -0 // true
NaN === NaN // false
assign
Object.assign(目标对象, 源对象1, 源对象2 ...),返回目标对象。
将源对象上可枚举和直接拥有的属性拷贝到目标对象,并且是浅拷贝。
create
Object.create(proto,[propertiesObject])
该方法创建一个新对象,这个新对象的原型指向 proto
proto:新创建对象的原型对象
propertiesObject:属性对象,会添加到新创建对象上面
setPrototypeOf
Object.setPrototypeOf(a, b)
将 a 的原型指向 b。
isPrototypeOf
// Foo.prototype 在 a 的原型链上出现过吗?
Foo.prototype.isPrototypeOf( a );
// b 在 c 的原型链上出现过吗?
b.isPrototypeOf( c );
getPrototypeOf
Object.getPrototypeOf(obj) 返回指定对象的原型
属性
数据属性
ES5 中新增了属性描述符用来描述对象中的数据属性。
默认情况下,
3个描述符都为true。可写性 writable
writable决定是否可以修改属性值,如果为false,将不能修改。可配置性 configurable
configurable表示是否可以修改属性的描述符。如果
configurable被设置成false了,那么就不能再修改这3个描述符,尝试修改会报错,同时,执行delete操作也会静默失败。当然,除了
writable,它比较特殊。如果
configurable变成false后,writable可以由true变成false,但是不能由false变成true。所以,
configurable是单向操作,一旦变为false,就不能再改成true。可枚举性 enumerable
它控制着一个属性是否能在特定的对象-属性枚举操作中(属性被迭代时)出现,比如:
for in循环Object.keys方法JSON.stringify方法设置为
false就不会出现在上述枚举和方法中,但是依然是可以通过对象访问的。propertyIsEnumerable方法可用于判断一个属性是否直接存在于对象上,并使是可枚举的。访问器属性
访问器属性包含两个函数:
getter和setter,分别在读取和设置属性值的时候调用。除此之外,还包括
configurable和enumerable。直接定义:
通过方法定义:
不可变性
对象常量
通过使用
writable和configurable可以使对象的属性不能修改和删除。防止扩展
禁止对象添加新的属性,如果添加会静默失败,严格模式下报错。
封印
Object.seal方法接收一个对象,它对这个对象做了两件事情:Object.preventExtensions方法,禁止其扩展configurable设置为true,所以,不能配置和删除属性但是,如说属性的
writable为true,就已然可以修改属性值。冻结
Object.freeze方法,相当于在seal的基础上,将属性的writable设置为false。对象的属性不能配置、删除,也不能修改。
属性存在性
in 操作符
in操作符会检查属性是否存在于对象或者其原型链的对象上。hasOwnProperty
hasOwnProperty方法也可以判断一个对象是否有某个属性,但是不会检查原型链。一般情况下,可以通过普通对象直接访问
hasOwnProperty方法,但是更好的方式是:这样可以防止
obj对象没有链接到Object.prototype,不能访问hasOwnProperty方法。对象的方法汇总
keys
返回一个所有可枚举属性的数组,不包括原型链上的属性。
Object.keys(obj);getOwnPropertyNames
返回一个所有属性的数组,不论是否可以枚举。
Object.getOwnPropertyNames(obj);propertyIsEnumerable
判断一个属性是否直接存在于对象,并且是可枚举的。
obj.propertyIsEnumerable('name');hasOwnProperty
判断对象是否直接拥有属性。
Object.prototype.hasOwnProperty.call(obj, "name");defineProperty
定义单个数据属性或访问器属性。
defineProperties
定义多个数据属性或访问器属性。
getOwnPropertyDescriptor
获取某个属性的属性描述符。
Object.getOwnPropertyDescriptor(obj, name);getOwnPropertyDescriptors
获取对象所有属性的属性描述符。
Object.getOwnPropertyDescriptors(obj);is
比较两个值是否严格相等。
assign
Object.assign(目标对象, 源对象1, 源对象2 ...),返回目标对象。将源对象上可枚举和直接拥有的属性拷贝到目标对象,并且是浅拷贝。
create
Object.create(proto,[propertiesObject])该方法创建一个新对象,这个新对象的原型指向
protoproto:新创建对象的原型对象propertiesObject:属性对象,会添加到新创建对象上面setPrototypeOf
Object.setPrototypeOf(a, b)将
a的原型指向b。isPrototypeOf
getPrototypeOf
Object.getPrototypeOf(obj)返回指定对象的原型