一、语法
对象可以通过两种形式定义:字面量和构造形式
// 字面量
var maObj = {
key: value
}
// 构造形式
var myObj = new Object()
myObj.key = value
这两种方式生成的对象是一样的。唯一的区别就是字面量可以添加多个键/值对,但是构造函数形式中只能逐个添加。
二、类型
1. null
- null有时被当作一种对象类型,但是其实只是语言的一个bug,即执行typeof null 时会返回字符串“Object”。
- 实际上,null本身是基本类型。
2. 函数
- 实际上,JavaScript中有许多特殊的对象子类型,可以称为复杂基本类型。
- 函数就是对象的子类型。JavaScript中的函数是“一等公民”,因为它们本质上和普通对象一样(只是可以调用),所以可以像操作其他对象一样操作函数(作为另一个函数的参数或返回值)。
3. 内置对象
JavaScript还有一些对象子类型,通过被称为内置对象。
String、Number、Boolean、Object、Function、Array、Date、RegExp、Error
- 这些内置对象从表现形式来说很像其他语言中的类型(type)或类(class)。
- 在JavaScript中,它们实际上只是一些内置函数。这些内置函数可以当作构造函数来用,从而可以构造一个对应子类型的新对象。
以String为例介绍一下作用
- 比如字符串“I am a string”并不是一个对象,只是一个原始类型,没有方法可以调用。
- 但如果要在该字符串上执行一些操作,比如获取长度、访问其中某个字符等,那需要将转换为String对象。
- 有需要时,引擎会自动把该字符串转换成一个String对象。
var str = "I am a string"
console.log(str.length) // 转换成Stirng对象,调用length方法。
数值类型也有类型的情况。
三、内容
对象的内容时由一些存储在特定命名位置的(任意类型)值组成的,我们称之为属性。
var obj = {
a: 2
}
obj.2 // 2
obj.[2] // 2
- .a语法通常被称为“属性访问”,.[“a”]通常被成为“键访问”。
- 在对象中属性名永远是字符串。
1. 可计算属性名
- ES6增加的可计算属性名,可以在文字形式中使用[]包裹一个表达式来当作属性名。
- 可计算属性名最常用的场景是ES6的符号(Symbol)。
var prefix = “foo”
var myObject = {
[prefix + "bar"]: "hello"
}
myObject["foobar"]; // hello
2. 属性和方法
- 函数不会属于某个对象,只是被对象所应用。
3. 数组
- 数组也是对象,所以虽然每个下标是整数,你仍然可以给每个数组添加属性。
var myArray = ["foo", 42, "bar"]
myArray.baz = "baz"
myArray.baz // "baz"
4. 复制对象
复制有深拷贝和浅拷贝。
深拷贝可以借助JSON字符串
var newObj = JSON.parse(JSON.stringify(someObj))
这种方法需要保证对象是JSON安全的,也就是只适用部分情况。
浅拷贝使用Object.assign(…)
5. 属性描述符
var myObject = {
a: 2
}
Object.getOwnPropertyDescriptor(myObject, "a")
//{
// value: 2,
// writeable: true,(可写)
// enumrable: true,(可枚举,比如for...in循环)
// configurable: true(可配置,特性可以被defineProperty()修改)
//}
可以通过Object.defineProperty()
来显示指定这些特性。
四、不变性
1. 对象常量
writable:false
和configurable: false
就可以创建一个真正的常量属性。
2. 禁止扩展
Object.prevent Extensions()
:禁止一个对象添加新属性并且保留已有属性。
3. 密封
Object.seal()
:密封之后不仅不能添加新属性,也不能重新配置或者删除任何现有属性。
4. 冻结
Object.freeze()
:无法修改所有属性的值。- 深度冻结:需要遍历它引用的所有对象,适用
Object.freeze()
5. Gette
和Setter
- 对象默认的[[Put]]和[Get]操作分别控制属性值的设置和获取。
- ES5中可以适用Getter和Setter部分改写默认操作,但是只能用在某个属性上,无法直接应用在整个对象上。
6. 存在性
- 通过in操作符判断改属性是否在对象中存在,但是可能是在原型链上。
Object.keys()
返回一个数组,包含所有可枚举属性。- 还有
for...in
五、遍历
for...in
遍历返回对象上所有可枚举属性。(遍历的是属性,通过属性名获取到属性值)for...of
遍历数组,直接遍历元素(属性名)。不能用于对象遍历。
六、总结
知识点比较散,做了简单的总结
- 对象由字面量形式和构造形式创建。字面量形式更常见,
- 对象是JS中的基础类型之一。对象中包含函数、数组等。
- 对象是键/值对的集合。属性不一定包含值,可能是具备getter和setter的“访问描述符”。
- 属性的特性可以通过属性描述符来控制。比如
writable
和configurable
。 - 复制对象有深拷贝和浅拷贝。
for...in
遍历对象的属性,然后通过属性名获取到属性值。for...of
遍历数组的元素(也就是可以直接获取到属性值)。