简介
- 属性名可以是包含空字符串在内的任意字符串,但对象中不能存在两个同名的属性。
- 值可以是任意 JavaScript 值,从 ES 5 开始也可以是
getter
和setter
函数(或者二者都有)。
- 属性特性有以下三种:
-
可写 :是否可以设置属性值。
-
可枚举 :是否可以通过
for/in
循环返回该属性值。
-
可配置 :是否可以删除或修改该属性。
- 在 ES 5 以前的所有属性都是 可写 、 可枚举 、 可配置 的。
属性的查询和设置
var ab = a.b;
var ac = a["c"];
a.b = 6;
a["c"] = 7;
- 对象可以动态地创建任意数量的属性。
- 动态创建对象属性时,通常用
[]
形式而不是.
形式,因为.
的属性名用的是标识符,而[]
用的属性名师字符串。
- 对象的 自有属性 可以覆盖 继承属性 ,但 继承属性 即使被 自有属性 覆盖,也仍然存在。
- 对象的 自有属性 覆盖 继承属性 的示例:
var o = {r : 1};
var c = inherit(o);
c.x = 2;
c.y = 2;
c.r = 2;
o.r; // 仍然为1,子对象c的覆盖行为不会影响到原型的属性
- 查询一个对象的不存在属性不会报错,会返回
undefined
。
- 查询一个不存在的对象的任意属性会抛出 类型错误异常 。
- 确保查询的对象存在的简单示例:
var len = a && a.b && a.b.c; // JavaScript中的&&不会将操作数转换为布尔值,同时返回的不一定是布尔值,可以是其他真值或假值
- 一些设置属性的操作在 ES 3 中会失败,但不会报错,在 ES 5 的 严格模式 中则报错:
- 给只读属性赋值。
- 使用 自有属性 覆盖只读的 继承属性 。
- 给不可拓展的对象增加属性。
删除属性
-
delete
只是断开属性和宿主对象的联系。
-
delete
只能删除 自有属性 ,不能删除 继承属性 ,可以直接在 原型对象 上删除它。
-
delete
的返回值取决于以下两点:
-
delete
删除成功或没有任何副作用时,返回true
。
-
delete
后不是一个属性访问表达式,返回true
。
-
delete
不能删除不可配置的属性。在 严格模式 下,删除不可配置的属性会报错。
o = {x : 1};
delete o.x; // true
delete o.y; // true
delete o.toString; // true
delete 1; // true
delete Object.prototype; // false,无法删除,属性是不可配置的
var x = 1; // false,不可配置
delete this.x; // false,无法删除
function f() { }
delete this.f; // false,不能删除全局函数
检测属性
-
in
:如果对象的 自有属性 或 继承属性 中包含这个属性就返回true
。
var o = {x : 1};
"x" in o; // true
"y" in o; // false
"toString" in o; // true
-
hasOwnProperty()
:如果对象的 自有属性 中包含这个属性就返回true
。
var o = {x : 1};
o.hasOwnProperty("x"); // true
o.hasOwnProperty("y"); // false
o.hasOwnProperty("toString"); // false
-
propertyIsEnumerable()
:如果对象的可枚举 自有属性 中包含这个属性就返回true
。通常 JavaScript 创建的属性都是可枚举的。
var o = inherit({y : 2});
o.x = 1;
o.propertyIsEnumerable("x"); // true
o.propertyIsEnumerable("y"); // false
Object.prototype.propertyIsEnumerable("toString"); // false
枚举属性
-
for/in
循环可以用于遍历对象中所有可枚举的属性(包括 自有属性 和 继承属性 )。
- 对象继承的内置方法不可枚举的,但在代码中给对象添加的属性都是可枚举的。
-
ES 5 两个和枚举相关的函数:
-
Object.keys()
:返回一个数组,元素为对象中可枚举的 自有属性 的名称。
-
Object.getOwnPropertyNames()
:返回一个数组,元素为对象中 自有属性 的名称。
属性的getter
和setter
- 使用常见的键值对的方式定义的属性,称为 数据属性 。另一种通过定义
getter
和setter
一个或两个的方式定义的属性,称为 存取器属性 。
- 和 数据属性 一样, 存取器属性 也可以被继承。
- 如果一个 存取器属性 :
- 定义了
getter
和setter
则是一个 读/写属性 。
- 定义了
getter
则是一个 只读属性 。
- 定义了
setter
则是一个 只写属性 。
- 读取 只写属性 总是返回
undefined
。
var o = {
odata = 0;
get data() { return odata; }, // 逗号
set data(value) { odata = value; }
}
o.data; // 0
o.data = 10;
属性的特性
属性描述符
简述
-
属性描述符 是一个对象,记录了 数据属性 或 存取器属性 的四个特性。
-
Object.getOwnPropertyDescriptor()
:
- 可以用于获取某个对象的 自有属性 的 属性描述符 。
- 要想获取 继承属性 的 属性描述符 则需要遍历原型链。
-
Object.definePeoperty()
:
- 可以用于设置某个对象的 自有属性 的 属性描述符 ,或者新建具有某种 属性描述符 的 自有属性 。
- 要想设置 继承属性 的 属性描述符 则需要遍历原型链。
-
Object.definePeoperties()
:
- 和
Object.definePeoperty()
一样,但是可以同时设置或新建多个 自有属性 。
- 要想设置 继承属性 的 属性描述符 则需要遍历原型链。
-
Object.definePeoperty()
和Object.definePeoperties()
会在违反以下原则时抛出类型错误异常:
- 如果对象不可拓展,那么可以编辑此对象的 自有属性 ,但是不能添加新属性。
- 如果属性不可配置,则:
- 不能修改 可配置性 和 可枚举性 。
- 将 数据属性 转换为 存取器属性 或反方向转换。
- 可以关闭 可写性 ,但不能打开 可写性 。
Object.getOwnPropertyDescriptor()
示例
// 返回 {value: 1, writable:true, enumerable:true, configurable:true}
Object.getOwnPropertyDescriptor({x : 1}, "x");
var random = {
get octet() { return Math.floor(Math.random() * 256); }
};
// 返回 { get: /*func*/, set:undefined, enumerable:true, configurable:true}
Object.getOwnPropertyDescriptor(random, "octet");
Object.getOwnPropertyDescriptor({}, "x"); // undefined
Object.getOwnPropertyDescriptor({}, "toString"); // undefined
Object.definePeoperty()
示例
var o = {};
// 定义属性o.x
Object.defineProperty(o, "x", {
value : 1,
writable : true,
enumerable : false,
configurable : true
});
// 设置o.x为不可写
Object.defineProperty(o, "x", {writable : false});
// o.x虽然不可写,但是仍然可配置,所以可以通过这种方式修改值
Object.defineProperty(o, "x", {value : 2});
// 可以将数据属性修改为存取器属性
Object.defineProperty(o, "x", {
get : function () { return 0; }
});
Object.definePeoperties()
示例
var p = Object.defineProperties({}, {
x : {value : 1, writable : true, enumerable : true, configurable : true},
y : {value : 1, writable : true, enumerable : true, configurable : true},
r : {
get : function () {
return Math.sqrt(this.x * this.x + this.y * this.y)
},
enumerable : true,
configurable : true
}
});
数据属性
-
数据属性 包含以下四个特性:
-
value
: 值
-
writable
: 可写性
-
enumerable
: 可枚举性
-
configurable
: 可配置性
存取器属性
-
存取器属性 包含以下四个特性:
-
get
: 读取
-
set
: 写入
-
enumerable
: 可枚举性
-
configurable
: 可配置性