文章目录
对象
这部分对JS中的对象(Object)进行了讲解,但由于对象、函数和数组之间有很强的关联,所以这部分只做了简单的介绍,还有部分知识会在学习函数或数组时进行补充。
1 对象介绍
1.1 数据类型比较
- 原始值
- 数值 Number
- 大整数 BigInt
- 字符串 String
- 布尔值 Boolean
- 空值 Null
- 未定义 Undefined
- 符号 Symbol
- 对象
- 对象是JS中的一种复合数据类型,
- 它相当于一个容器,在对象中可以存储各种不同类型数据
- 使用typeof检查一个对象时,会返回
'object'
- 区别:
- 原始值只能表示一些简单的数据,不能表示复杂的数据
1.2 定义对象
例如如下定义
let name = "张三"
let age = 18
let gender = "男"
虽然也定义了人的三个属性,但是从代码中看不出来这三个属性描述的是同一个人,所以我们需要一种方法,可以将三个属性绑定到一个东西上去,这个东西在JS就叫做对象
// 创建对象
let person = Object()
person.name = "张三"
person.age = 18
person.gender = "男"
// 修改属性
person.name = "Tom sun"
// 删除属性
delete person.name
console.log(person.name)
从上面的代码可以看出,我们将一个人的三个属性绑定到一个叫做person的对象上,通过运算符.
来获取对象的某个属性
其中
- 对象中可以存储多个各种类型的数据,对象中存储的数据,我们称为属性
- 向对象中添加属性:对象.属性名 = 属性值
- 读取对象中的属性:对象.属性名
如果读取的是一个对象中没有的属性,不会报错而是返回undefined
2 属性
2.1 属性名
通常属性名就是一个字符串,所以属性名可以是任何值,没有什么特殊要求
如果你的属性名太特殊了,不能直接使用,需要使用[]
来设置
let obj = Object()
obj.name = "孙悟空"
// obj.if = "哈哈" // 不建议
// obj.let = "嘻嘻"// 不建议
// obj["1231312@#@!#!#!"] = "呵呵"// 不建议
虽然如此,但是我们还是强烈建议属性名也按照标识符的规范命名
也可以使用符号(symbol)作为属性名,来添加属性;获取这种属性时,也必须使用symbol
使用symbol添加的属性,通常是那些不希望被外界访问的属性
let obj = Object()
let mySymbol = Symbol()
let newSymbol = Symbol()
// 使用symbol作为属性名
obj[mySymbol] = "通过symbol添加的属性"
console.log(obj[mySymbol]) // 通过symbol添加的属性
console.log(obj[newSymbol]) // undefined
使用[]
去操作属性时,可以使用变量
let obj = {
name: "zhangsan"
}
let str = "name"
console.log(obj[str]) // "zhangsan", 等价于 obj.name 或者 obj["name"]
2.2 属性值
对象的属性值可以是任意的数据类型,也可以是一个对象
let obj = Object()
obj.a = 123
obj.b = 'hello'
obj.c = true
obj.d = 123n
obj.f = Object()
obj.f.name = "猪八戒"
obj.f.age = 28
2.3 in运算符
- 用来检查对象中是否含有某个属性
- 语法 属性名 in obj
- 如果有返回true,没有返回false
let obj = Object()
obj.name = "123"
console.log("name" in obj) //true
console.log("age" in obj) //false
3 对象字面量
在创建对象的时候可以使用Object()
来创建,也可以使用{}
来创建对象
-
使用
{}
所创建的对象,可以直接向对象中添加属性 -
语法:
let obj = { 属性名:属性值, 属性名:属性值, [属性名]:属性值, }
示例代码:
let obj = Object()
let mySymbol = Symbol()
let obj2 = {
name:"孙悟空",
age:18,
["gender"]:"男",
[mySymbol]:"特殊的属性",
hello:{
a:1,
b:true
}
}
console.log(obj)
console.log(obj2)
4 枚举类型
枚举属性,指将对象中的所有的属性全部获取
4.1 for - in语句
语法:
for(let propName in 对象){
语句...
}
for-in的循环体会执行多次,有几个属性就会执行几次,每次执行时,都会将一个属性名赋值给我们所定义的变量
注意:并不是所有的属性都可以枚举,比如 使用符号(Symbol)添加的属性
let obj = {
name:'孙悟空',
age:18,
gender:"男",
address:"花果山",
[Symbol()]:"测试的属性" // 符号添加的属性是不能枚举
}
for(let propName in obj){
console.log(propName, obj[propName])
}
5 可变类型
这里非常重要,如果不懂的话看这个https://www.bilibili.com/video/BV1mG411h7aD?p=50
5.1 回顾不可变类型
- 原始值都属于不可变类型,一旦创建就无法修改
- 在内存中不会创建重复的原始值
当我们为一个变量重新赋值时,绝对不会影响其他变量
- 对象属于可变类型
- 对象创建完成后,可以任意的添加删除修改对象中的属性
- 注意:
- 当对两个对象进行相等或全等比较时,比较的是对象的内存地址
- 如果有两个变量同时指向一个对象,通过一个变量修改对象时,对另外一个变量也会产生影响
5.2 对象的存储方式
对象的内存存储方式如下图
为了简单表现,就把0x33地址处的孙悟空直接放进表格中了,在修改的时候其实改的也是name指向的地址
所谓的可变指的就是obj指向的0x22地址区域中的值是可以变的
对比基础类型的变量指向区域的值是不可改变的
5.3 对象的比较
每次调用Object()
都会在内存区域中开辟出一块新的区域
当对两个对象进行相等或全等比较时,比较的是对象的内存地址
所以如果比较obj2 === obj3
得到值是false
如果是下面这种情况,最终得到的结果是true
let obj2 = Object()
let obj3 = obj2
console.log(obj2 === obj3) // true
5.4 指向相同对象
如果在代码中把一个对象赋值给另一个对象的话,会让两个变量指向同一块内存区域
如果修改一个对象的值,由于两个对象指向的是同一片内存地址,那么另一个对象的属性值也会被修改掉(因为两个本来其实就是一个对象,所以一个修改掉的话另一个看到的也是修改后的结果)
5.5 修改对象和修改变量
-
修改对象
-
修改对象时,如果有其他变量指向该对象,则所有指向该对象的变量都会受到影响
-
-
修改变量
-
修改变量时,只会影响当前的变量
-
-
在使用变量存储对象时,很容易因为改变变量指向的对象,提高代码的复杂度,所以通常情况下,声明存储对象的变量时会使用const
注意:const只是禁止变量被重新赋值,对对象的修改没有任何影响