对象
对象可以通过两种方式定义:生命(文字)形式和构造形式。
类型
六种主要类型:string、boolean、number、null、undefined和object。
typeof null 会返回字符串“object”,这是一个bug。
原理是这样的,不同对象在底层都表示为二进制,在JavaScript中二进制前三位都是0的话会被判断为object类型,null的二进制表示全为0,自然前三位也是0,所以执行typeof时会返回“object”。
内置对象
- String
- Number
- Boolean
- Object
- Function
- Array
- Date
- RegExp
- Error
这些内置对象从表现形式来说很像其他语言中的类型(type)或者类(class),比如Java中的String类。
这些内置函数可以当做构造函数使用,从而可以构造一个对应子类型的新对象。例如:
1 | var strPrimitive = "I am a string"; |
内容
访问属性有两种方式:“属性访问”和“键访问”。
1 | var myObject = { |
在对象中,属性名永远都是字符串。如果你是用string(字面量)以外的其他值作为属性名,那它首先会被转换为一个字符串。
属性和方法
函数不会“属于”一个对象————它们只是对于相同函数对象的多个引用。
复制对象
这里涉及到浅复制和深复制。
属性描述符
1 | var myObject = { |
writable(可写)、enumerable(可枚举)和configurable(可配置)。
通过使用Object.defineProrerty(..)来添加一个新属性或者修改一个已有属性(如果他是configurable)并对特性进行设置。
不变性
1.对象常量
结合writable:false
和configurable:false
就可以创建一个真正的常量属性(不可修改、重定义或者删除)
2.禁止扩展
使用Object.preventExtensions(..)
可以禁止一个对象添加新属性并且保留已有属性。
3.密封Object.seal(..)
会创建一个“密封”对象,这个方法实际上会在一个现有对象上调用Object.prenvenExtensions(..)
并把所有现有属性标记为configurable:false
。与禁止扩展不同的是,“密封”后不能重新配置任何现有属性。
4.冻结Object.freeze(..)
相当于调用Object.seal(..)
之后并把所有的“数据访问”属性标记为writable:false
。
存在性
myObject.a的属性访问返回值可能是undefined
,但是这个值有可能是属性中存储的undefined
,也可能是因为属性不存在所以返回undefined
。如何区分这两种情况呢?
1 | var myObject = { |
不同的是in会访问原型链,hasOwnProperty(..)
不会检查原型链。Object.propertyIsEnumerable(..)
会检查给定的属性名是否直接存在于对象中并且满足emumerable:true
;Object.keys(..)
会返回一个数组,包含所有可枚举属性;Object.getOwnPropertyNames(..)
返回一个数组,包含所有属性,无论他们是否可枚举。