简介
-
JavaScript 中的对象时动态的,属性可以增删,当常用来模拟静态对象以及静态类型语言中的 结构体 。
-
类 :标识对象类型的字符串。
-
拓展标记 :是否可以添加新属性。
- 对象的种类有: 内置对象 、 宿主对象 (由 宿主环境 定义,可以当做 内置对象 )、 自定义对象 。
- 对象也是 关联数组 、 散列 、 映射 、 字典 。
三种创建方式
对象直接量
var empty = {};
var abc = {
abcdef: "str", // 属性名可以是一个标识符
"abcdef": 123, // 属性名可以是一个字符串
"abc def": 123, // 有空格的属性名必须是一个字符串
'abc-def': true // 有连字符的属性名必须是一个字符串
};
new
function Point(x, y) {
this.x = x;
this.y = y;
}
var p = new Point(1, 1);
// 不需要传入任何参数给构造函数时,可以省略括号
new Object
new Date
Object.create()
-
ES 5 定义了
Object.create()
。
- 简单示例:
var o1 = Object.create({x : 1, y : 2}); // 创建了o1对象,o1继承了属性x和y
var o2 = Object.create(null); // 创建了o2对象,o2不继承任何属性和方法
var o3 = Object.create(Object.prototype); // 创建了o3对象,o3和{}和new Object()一样
function inherit(p) {
if (p === null) throw TypeError();
if (Object.create) return Object.create(p);
var t = typeof p;
if (t !== "object" && t !== "function") throw TypeError();
function f() {
}
f.prototype = p;
return new f();
}
- 上述中的
inherit()
有防止库函数无意间修改的作用:
var o = {x : "don't change this value"};
library_function(inherit(o)); // 通过继承时拷贝继承的属性,来避免意外修改了o
序列化对象
-
对象序列化 是指将对象的状态转换为字符串。
-
ES 5 提供了
JSON.stringify()
和JSON.parse()
用来 序列化 和 反序列化 JavaScript 对象。
-
JSON.stringify()
和JSON.parse()
都可以接受第二个可选参数,通过传入需要 序列化 或 反序列化 的属性列表来定制自定义的 序列化 或 反序列化 操作。
-
序列化 与 反序列化 的规则:
- 对象、数组、字符串、有限数字、
true
、false
、null
可以 序列化 和 反序列化 。
-
NaN
、Infinity
和-Infinity
序列化 结果为null
。
-
Data
对象 序列化 为 ISO 格式的日期字符串, 反序列化 为字符串,而不是Data
对象。
- 函数、
RegExp
对象、Error
对象和undefined
不可以 序列化 或 反序列化 。
-
JSON.stringify()
只能 序列化 对象 可枚举 的 自有属性 ,对于不能 序列化 的属性会被省略。
继承于Object
的方法
toString()
方法
- 默认的
toString()
并不会输出很多有用的信息。
- 很多类都带有自定义
toString()
,如数组、函数和Data
对象等。
toLocaleString()
方法
- 通常
toLocaleString()
仅仅调用toString()
并返回对应的值。
-
Data
对象和Number
对象因为有本地化的需求,所有做了定制。
- 数组的
toLocaleString()
不是调用数组的toString()
并返回对应的值,而是调用每个元素的toString()
并返回对应的值。
toJSON()
方法
- 通常没有定义
toJSON()
方法,但是如果定义了,那么JSON.stringify()
会调用它。
valueOf()
方法
对象的三个属性
原型属性
-
原型属性 记录着这个对象继承的对象。
-
原型属性 是在实例对象创建之前就设置好的。
- 在 ES 5 中,可以使用
Object.getPrototypeOf()
来查询对象的 原型 。
- 可以使用
Object.isPrototypeOf()
来检测一个对象是否是另一个的 原型 。
类属性
简述
- 对象的 类属性 是一个字符串,用来表示对象的类型信息。
-
自定义对象 的 类属性 都是
Object
,无法用于区分对象的类对于其它对象,如 内置对象 的 类属性 有所不同
- 没有直接查询这个属性的方法,只有一种间接的查询方法,通过提取
toString()
返回的字符串的第8个到倒数第2个位置之间的字符,可以使用classof()
工具函数:
简单示例
function classof(o) {
if (o === null) return "Null";
if (o === undefined) return "undefined";
return Object.prototype.toString.call(o).slice(8, -1);
}
classof(null) // "Null"
classof(1) // "Number"
classof("") // "String"
classof(false) // "Boolean"
classof({}) // "Object"
classof([]) // "Array"
classof(/./) // "RegExp"
classof(new Date()) // "Date"
classof(window) // "Window" (a client-side host object)
function f() { };
classof(new f()); // "Object"
可拓展性
简述
- 对象 可拓展性 用来表示是否可以给对象添加新属性。
- 所有 内置对象 和 自定义对象 都是显式可拓展的, 宿主对象 的 可拓展性 则由 JavaSctipt引擎 定义。
-
Object.preventExtensions()
:
- 用于将对象从可拓展转换为不可拓展。
- 此操作不可逆。
- 尽管此对象转换为不可拓展后,不能直接添加属性,但是如果给其 原型对象 添加属性,这个对象依旧会继承新添加的 继承属性 。
- 可以使用
Object.isExtensible()
来检测对象的 可拓展性 。
-
Object.seal()
:
- 用于将对象从可拓展转换为不可拓展, 且 所有 自有属性 都设置为不可配置。
- 此操作不可逆。
- 可以使用
Object.isSealed()
来检测对象是否封闭。
-
Object.freeze()
:
- 用于将对象从可拓展转换为不可拓展、所有 自有属性 都设置为不可配置, 且 所有 自有数据属性 都设置为只读, 存取器属性 依然可写。
- 此操作不可逆。
- 可以使用
Object.isFrozen()
来检测对象是否冻结。