每天一章犀牛书——CHAP6:对象

对象是属性的无序集合。因此,这一章主要从对象和属性两个方面来阐述。

1. 对象

1.1 对象的定义

对象是属性的无序集合,也可以看做是从字符串到值的映射。

1.2 对象的分类

对象可分为三类:
  1. 内置对象(native object):由ECMAScript规范定义的对象。如数组、函数、日期、正则表达式等都是内置对象。

  2. 宿主对象(host object):JS解释器所嵌入的宿主环境(比如Web浏览器)定义的。如客户端JS中的HTMLElement对象就是宿主对象。

  3. 自定义对象(user-defined object):运行中的JS代码创建的对象。

1.3 对象的操作

1.3.1 创建对象

创建对象主要有3种方法:对象直接量、new运算符、Object.create()(1) 对象直接量:    `var empty = {}`    `var point = {x:0,y:0}` (2) new运算符:new + 函数调用(该函数称为构造函数constructor).使用对象直接量创建对象相当于使用 new Object() (3) `Object.create()`  每一个JS对象(null除外)都和另一个对象相关联,另一个对象就是该对象的原型。  使用对象直接量创建的对象的原型就是Object.prototype,使用new运算符创建的对象的原型是构造函数的prototype的值。 Object.create()接受两个参数。第一个是要创建的对象的原型对象,第二个可选,内容是属性描述符。 对于前两种创建对象的方法,用Object.create()表示即为:Object.create(Object.prototype),Object.create(Func.prototype). 当有第二个参数时:
        var bob = Object.create(userB, {     'id' : {       value: MY_GLOBAL.nextId(),       enumerable:true // writable:false, configurable(deletable):false by default     },     'name': {       value: 'Bob',       enumerable: true     }        });

1.3.2 序列化对象

对象序列化是指将对象的状态转化为字符串,也可将字符串还原为对象。函数、RegExp、Error、undefined值不能序列化和还原。`JSON.stringify()`将任意的JavaScript值序列化成JSON字符串,并且 只能序列化对象的可枚举属性 。`JSON.parse()`将一个 JSON 字符串解析成为一个 JavaScript 值。

1.4 对象的方法

所有的对象都会从Object.prototype继承属性和方法(除了以null为原型),这里先介绍Object.prototype的几个方法,其他的将会在后面的部分介绍。
  1. toString():返回调用这个方法的对象值的字符串。返回信息少。在需要将对象转换为字符串的时候,JS会调用这个方法。

  2. toLocaleString():返回对象的本地化字符串。Object的该方法调用toString(),Date 和 Number 则对日期、数字做本地化的转换。

  3. valueOf():返回对象的原始值。

1.5 对象的属性

  1. 原型属性:每个对象都有一个原型(Object.prototype除外),ECMAScript提供了两种方法查询对象的原型。

Object.getPrototypeOf():返回作为参数传入的对象的原型。

  1. isPrototypeOf():检测一个对象是否是另一个对象的原型。p.isPrototypeOf(o)检测p是否是o的原型。

  2. 可扩展性:是否可以给对象添加新属性。主要目的是将对象锁定,避免外界干扰。关于可扩展性有以下几种方法:

Object.isExtensible() :检测传入的对象是否是可扩展的,返回布尔值。

  1. Object.preventExtens() :将对象设置为不可扩展的,意味着不能给对象添加新的属性。将对象设置为不可扩展后不能重新设置为可扩展。

  2. Object.seal():将对象设置为不可扩展+不可配置自有属性,意味着不能给对象添加新的属性+不能对已有属性进行删除或配置。

  3. Object.isSeal():判断对象是否封闭(seal)。

  4. Object.freeze():不可扩展+不可配置+数据属性只读。

  5. Object.isFrozen()判断对象是否冻结(freeze)

2.属性

2.1 属性的分类

a.按照原型和继承可分为: 继承属性和自由属性。b.按照属性的描述符可分为: 数据属性和存取器属性(accessor property)。

2.2 属性的描述符

属性的描述符主要是对针对属性可以进行的操作的描述。数据属性和存取器属性共有的属性描述符是:
  1. enumerable:是否可枚举,即能佛欧通过for/in 或者 Object.keys()循环。

  2. configurable: 是否可以删除属性或者对属性描述符进行修改。如果configurable为false,则不能对writable之外的描述符进行修改,同时数据属性和存取器属性不可转换。也不能将可写性从false改为true。
    数据属性单独有的属性描述符是:

  3. value:属性的值。

  4. writable:属性的值是否可通过赋值运算符修改。
    存取器属性单独有的属性描述符是:

  5. set:给属性提供setter方法,若无则为undefined.

  6. get:给属性提供getter方法,若无则为undefined.

针对属性的描述符有以下几种方法:

  1. Object.getOwnPropertyDescriptor() :获得对象的特定的自有属性的属性描述符。第一个参数为对象,第二个为属性名。

  2. Object.defineProperty(obj, prop, descriptor) :给对象添加新的属性或者修改已有属性的属性描述符,并返回该对象。通过该方法添加的属性,其默认的属性描述符都为false.通过赋值运算符设置的属性的属性描述符默认为true.

  3. Object.defineProperties(obj, props):同时修改或添加多个属性。

2.3 对属性的操作

2.3.1 查询和设置

有两种方式可查询设置对象的属性:.和[]。.的右侧必须是有效标识符且不能是保留字。而[]则可以动态获取属性以及可以转换为字符串的属性。由于[]访问与数组很相似,因此也叫作关联数组。属性的赋值会先检查原型链,若原型链有该属性且该属性为不可写,则不能给该属性赋值。若原型链存在且可写,或者原型链不存在该属性,则该属性就变为自有属性,且不会修改原型对象的属性值。

2.3.2 删除属性

`delete`可删除对象的自有属性且configurable为true的属性。注意:delete只是断开属性与对象的关系,而不是操作属性中的属性。由此可能造成内存泄漏。

2.3.3 检测属性

检测属性主要检测两方面:(1)属性是否存在在对象中;(2)哪些属性是自有属性.提供的方法如下:
  1. in操作符。检测自有和继承属性中是否包含该属性。同时若属性值为undefined,返回true,若属性不存在返回false. property in obj

  2. hasOwnProperty(): obj.hasOwnProperty("x")检测属性”x”是否是obj对象的自有属性。

  3. propertyIsEnumerable(): obj.propertyIsEnumerable("x")检测属性”x”是否是obj对象的自有属性+该属性是否可枚举.当同时为true时才返回true.

2.3.4 枚举属性

枚举属性主要有三种方法:
  1. for/in:遍历所有可枚举的自有+继承属性。把属性名称赋值给循环变量。(枚举+所有)

  2. Object.keys():以数组形式返回对象的所有可枚举自有属性的名称。(枚举+自有)

  3. Object.getOwnpropertyNames():以数组形式返回对象的所有自有属性。(自有+可枚举+不可枚举)

关键字:JavaScript

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部