每天一章犀牛书——CHAP6:对象
对象是属性的无序集合。因此,这一章主要从对象和属性两个方面来阐述。
1. 对象
1.1 对象的定义
对象是属性的无序集合,也可以看做是从字符串到值的映射。
1.2 对象的分类
对象可分为三类:
内置对象(native object):由ECMAScript规范定义的对象。如数组、函数、日期、正则表达式等都是内置对象。
宿主对象(host object):JS解释器所嵌入的宿主环境(比如Web浏览器)定义的。如客户端JS中的HTMLElement对象就是宿主对象。
自定义对象(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的几个方法,其他的将会在后面的部分介绍。
toString():返回调用这个方法的对象值的字符串。返回信息少。在需要将对象转换为字符串的时候,JS会调用这个方法。
toLocaleString():返回对象的本地化字符串。Object的该方法调用toString(),Date 和 Number 则对日期、数字做本地化的转换。
valueOf():返回对象的原始值。
1.5 对象的属性
- 原型属性:每个对象都有一个原型(Object.prototype除外),ECMAScript提供了两种方法查询对象的原型。
Object.getPrototypeOf():返回作为参数传入的对象的原型。
isPrototypeOf():检测一个对象是否是另一个对象的原型。p.isPrototypeOf(o)检测p是否是o的原型。
可扩展性:是否可以给对象添加新属性。主要目的是将对象锁定,避免外界干扰。关于可扩展性有以下几种方法:
Object.isExtensible() :检测传入的对象是否是可扩展的,返回布尔值。
Object.preventExtens() :将对象设置为不可扩展的,意味着不能给对象添加新的属性。将对象设置为不可扩展后不能重新设置为可扩展。
Object.seal():将对象设置为不可扩展+不可配置自有属性,意味着不能给对象添加新的属性+不能对已有属性进行删除或配置。
Object.isSeal():判断对象是否封闭(seal)。
Object.freeze():不可扩展+不可配置+数据属性只读。
Object.isFrozen()判断对象是否冻结(freeze)
2.属性
2.1 属性的分类
a.按照原型和继承可分为: 继承属性和自由属性。b.按照属性的描述符可分为: 数据属性和存取器属性(accessor property)。
2.2 属性的描述符
属性的描述符主要是对针对属性可以进行的操作的描述。数据属性和存取器属性共有的属性描述符是:
enumerable:是否可枚举,即能佛欧通过for/in 或者 Object.keys()循环。
configurable: 是否可以删除属性或者对属性描述符进行修改。如果configurable为false,则不能对writable之外的描述符进行修改,同时数据属性和存取器属性不可转换。也不能将可写性从false改为true。
数据属性单独有的属性描述符是:value:属性的值。
writable:属性的值是否可通过赋值运算符修改。
存取器属性单独有的属性描述符是:set:给属性提供setter方法,若无则为undefined.
get:给属性提供getter方法,若无则为undefined.
针对属性的描述符有以下几种方法:
Object.getOwnPropertyDescriptor() :获得对象的特定的自有属性的属性描述符。第一个参数为对象,第二个为属性名。
Object.defineProperty(obj, prop, descriptor) :给对象添加新的属性或者修改已有属性的属性描述符,并返回该对象。通过该方法添加的属性,其默认的属性描述符都为false.通过赋值运算符设置的属性的属性描述符默认为true.
Object.defineProperties(obj, props):同时修改或添加多个属性。
2.3 对属性的操作
2.3.1 查询和设置
有两种方式可查询设置对象的属性:.和[]。.的右侧必须是有效标识符且不能是保留字。而[]则可以动态获取属性以及可以转换为字符串的属性。由于[]访问与数组很相似,因此也叫作关联数组。属性的赋值会先检查原型链,若原型链有该属性且该属性为不可写,则不能给该属性赋值。若原型链存在且可写,或者原型链不存在该属性,则该属性就变为自有属性,且不会修改原型对象的属性值。
2.3.2 删除属性
`delete`可删除对象的自有属性且configurable为true的属性。注意:delete只是断开属性与对象的关系,而不是操作属性中的属性。由此可能造成内存泄漏。
2.3.3 检测属性
检测属性主要检测两方面:(1)属性是否存在在对象中;(2)哪些属性是自有属性.提供的方法如下:
in操作符。检测自有和继承属性中是否包含该属性。同时若属性值为undefined,返回true,若属性不存在返回false. property in obj
hasOwnProperty(): obj.hasOwnProperty("x")检测属性”x”是否是obj对象的自有属性。
propertyIsEnumerable(): obj.propertyIsEnumerable("x")检测属性”x”是否是obj对象的自有属性+该属性是否可枚举.当同时为true时才返回true.
2.3.4 枚举属性
枚举属性主要有三种方法:
for/in:遍历所有可枚举的自有+继承属性。把属性名称赋值给循环变量。(枚举+所有)
Object.keys():以数组形式返回对象的所有可枚举的自有属性的名称。(枚举+自有)
Object.getOwnpropertyNames():以数组形式返回对象的所有自有属性。(自有+可枚举+不可枚举)
关键字:JavaScript
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!