★06.对象

简介

  • 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()一样
  • ES 3 中通过如下手段模拟:
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()都可以接受第二个可选参数,通过传入需要 序列化反序列化 的属性列表来定制自定义的 序列化反序列化 操作。
  • 序列化反序列化 的规则:
    • 对象、数组、字符串、有限数字、truefalsenull可以 序列化反序列化
    • NaNInfinity-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()来检测对象是否冻结。

你可能感兴趣的:(★06.对象)