6.1 对象的三大属性
原型prototype:指向另一个对象,本对象属性继承自它。
类class:标识对象类型的字符串,如:“[Object object]”。自定义类也显示为object,所以不能用class判断。
可扩展标记extensible flag:是否向此对象添加新属性。
几个名词的解释:
内置对象native object:js规范定义的类。如数组、函数、日期、正则。
宿主对象host object:js解释器嵌入的宿主环境,如浏览器。
自定义对象user-defined object:运行时js创建的对象。
自有属性own property:直接在对象中定义的属性。
继承属性inherited property:对象的原型对象定义的属性。
6.2.3 给对象o设置属性p会失败的场景
o中p属性只读。例外是使用defineProperty()。
o中p属性是继承来的,且是只读的。不能用同名自由属性覆盖只读的继承属性。
o没有自有属性p且没有继承属性p,且o可扩展性为false。
6.3 删除属性
delete只是断开属性和宿主对象的联系,而不会操作属性。
a={p:{x:1}} b=a.p delete a.p /*执行后b.x==1。需要遍历删除对象的属性,并递归删除*/
6.4 检测属性
in左侧为属性名(字符串),右侧是对象。如果对象自有属性或继承属性存在该属性则返回true。
对象的hasOwnProperty检测是否有自有属性。
对象的propertyIsEnumerable是hasOwnProperty的增强版,检测是自有属性且可枚举。
注意,若用o[p]!==undefined检测属性,则值等于undefined的属性会被误判。此时只能用in判断。
6.5 枚举属性
for in循环会枚举继承属性和方法,需要用hasOwnProperty和typeof!=="function"过滤。
Object.keys()返回对象的自有可枚举属性的名称数组。
Object.getOwnPropertyNames()比Object.keys()还多返回不可枚举属性。
6.6 属性getter和setter
读/写属性:有setter和getter方法
读属性:只有getter
写属性:只有setter,读值返回undefined
var o={ /*定义一个读写属性data_prop*/ get data_prop(){}, set data_prop(val){}, /*定义一个只读属性read_only*/ get read_only(){}, /*定义一个只写属性write_only*/ set write_only(val){},
/*别忘了结尾的逗号*/ }
注意,getter,setter方法中的this指向所在的对象,即不同的o中getter,setter指向不同的o。可以通过this访问对象的其它属性。
6.7 属性的特性
属性的特性为值value,可写性writable,可枚举性enumerable,可配置性configurable。
js用“属性描述符”property discriptor对象描述上述四个特性。用Object.getOwnPropertyDiscriptor(objectName,propertyName)得到自有属性的特性对象。
若该属性是一般方法定义的(o:{x:1}或o['x']=1中的x),则返回{value:,writable:boolean,enumerable:boolean,configurable:boolean}
若该属性是getter或setter定义的,则返回{set:function,set:function,enumerable:boolean,configurable:boolean}
用Object.defineProperty(objectName,propertyName,propertyDiscriptor)创建或修改一个对象的属性,其中propertyDiscriptor可以是上述两种之一。
defineProperties则传入(objectName,{propertyName:propertyDiscriptor,propertyName2:propertyDiscriptor2})一次性修改多个属性。
6.8.1 原型属性
Object.isPrototypeOf()和instanceOf很像,函数作用如其名。
6.9 序列化对象
JSON.parse保留日期格式的字符串形态,并不会还原成日期对象。同理,函数,RegExp,Error,undefined值不能被序列化和还原。
JSON.stringify只序列化对象可枚举的自有属性。