JS 也有面向对象
又到了我第 114514 喜欢的 CRUD 环节
Create
创建属性一般有两种办法
- 在对象声明时创建
- 在对象声明后插入
声明对象
一般有两种
直接创建
1
2
3let obj={
x:1
}通过 Object 对象方法创建
1
2
3let obj=new Object({
x:1
})
为什么会有两种写法?因为第二种才是正规的
但是架不住第一种更方便,于是第一种也变成合法的了
obj 的键一定是字符串,所以可以写任意的键名,甚至包括 空字符串 和 emoji
需要注意的是,无论你怎么写 obj 的键,它在构造完成后都会变成字符串
可以通过 Object.keys(obj) 来查看
比如
键是数字的情况
1
2
3let obj={
2:'233'
}此时 obj 会拥有一个名为 ‘2’ 的键
有同名变量的情况
1
2
3
4let a=100;
let obj={
a:'233'
}此时 obj 会拥有一个名为 ‘a’ 的键
但还有 2 种情况例外
当 obj 是数字表达式的时候
1
2
3let obj={
1e2: '233'
}此时 obj 会拥有一个名为 ‘100’ 的键
当 obj 使用方括号表达式的时候
1
2
3
4let a=233;
let obj={
[a]:'233'
}此时 obj 会拥有一个名为 ‘233’ 的键
而且,obj 在自动构建后会包含一个 __proto__
属性指向其原型
那我不要默认的 Object 原型,想要别的原型怎么办?
可以使用 Object.create 来创建来自指定原型的新对象
示例如下
1 | let common={ |
期望输出如下
1 | {yyy: 2} |
此时 a 可以访问属性 xxx 和 yyy,其中 yyy 来自自身,xxx 来自原型
需要注意的是,在 create 的第二个参数中,要求写的是属性描述符,一般包括
- value,属性值,必填
- writeable,默认 true,可以编辑,若为 false 则只读
- enumerable,默认 true,可以被枚举,若为 false 则不能通过简单的键遍历找到
- configureable,默认 true,可以被重新配置,若为 false 则永远在当前对象上保持当前状态
等 4 个配置
插入属性
一般有两种逐条插入的写法
- obj.property = value
- obj[property] = value
都是合法的写法
但是对于第一种,点号后必须是完整键名,不加引号
对于第二种,方括号内可以是表达式或字符串,如果可以识别为字符串,则字符串优先
示例如下
1 | let obj={ |
可见点符号的识别和方括号的识别是不一样的
还有一种批量插入的写法 Object.assign
1 | let obj={ |
期望输出如下
1 | {xxx: 111, yyy: 233, zzz: 114514} |
可见 assign 可以覆盖,可以新增,而且不会影响其他原有值
Retrieve
显然可以分为按键查找和按值查找两种类型
按键查找
可以使用以下两种方法
- in
- Object.hasOwnProperty
in 通过查找原型链确定某个参数是否存在于指定对象上
Object.hasOwnProperty 只会查找对象本身,不会上升到原型链
也可以用以下的 Object 方法来查找键或值
- Object.keys 列出所有键
- Object.values 列出所有值
- Object.entries 列出所有键值对
按值查找
通过上述的 entries 方法取得所有键值对,然后遍历即可
Update
可以使用
- 点符号
- 方括号
- Object.assign
- Object.defineProperty
来更新属性
需要注意的是,上述方法均不会直接修改到原型上
比如原型上有属性 xxx,当前对象 obj 上没有
则令 obj.xxx=’233’,会为当前对象绑定一个新属性 xxx,而不会修改原型上的
虽然可以通过 __proto__.xxx
来修改,但十分不推荐修改原型的属性
那如果直接修改原型呢?
虽然 JS 是允许直接通过 __proto__ = xxx
来修改对象的原型指向的,但性能十分之低下
如果一定要修改原型,最好在创建对象的时候使用 Object.create,在创建时就指定新的原型
Delete
一般有删除值和删除键两种需求
对于删除值,只需要取对应的键,然后赋值 undefined 即可
对于删除键,只需要使用 delete 语句
1 | delete obj.property; |
即可删除键
可以用 property in obj
查看 obj 中是否还含有指定键名
但待删除的键不可以是不可配置的(通过 Object.defineProperty 设置的不可配置)
需要注意的是,delete 语句用于删除属性时,在所有情况下都会返回 true 表示删除成功,即便 obj 中不存在目标键
除非将 delete 用于删除对象等非属性值,才会返回 false
谢谢阅读