1.对象含义和创建
- 含义:对象是拥有属性和方法的数据
- 创建方式一:字面量声明
var person = {}
var person = new Object()
2.增(添加属性)
var person = {}
person.name = "kyo"
- 通过api添加:Object.defineProperty(obj, key,options),默认只读且不可被枚举,如果属性已经存在,则相当于更新该属性的属性描述对象
属性名 |
默认值 |
说明 |
value |
|
属性值 |
writable |
false |
值是否可被修改,默认只读 |
configurable |
false |
属性是否可被重新配置 |
enumerable |
false |
是否可被枚举,默认false,不可被for in 和Object.keys() 遍历到 |
get |
|
function 属性被读取时执行 |
set |
|
function 属性被赋值时执行 |
//默认效果
var person = {
name:'key',
age:20
}
//基本使用
Object.defineProperty(person,'brithday',{
value:"2020-12-28",//默认值
})
- 获取属性描述对象:Object.getOwnPropertyDescriptor(obj,key)
<script>
//默认效果
var person = {
name:'key',
age:20
}
//基本使用
Object.defineProperty(person,'brithday',{
value:"2020-12-28",//默认值
})
console.log(Object.getOwnPropertyDescriptor(person, 'name'))
//{value: 'key', writable: true, enumerable: true, configurable:true}
console.log(Object.getOwnPropertyDescriptor(person, 'brithday'))
//{value: '2020-12-28', writable: false, enumerable: false, configurable: false}
</script>
3.删(删除属性)
- 通过运算符 delete 进行删除, 删除成功返回true,删除失败返回false
- 属性是只读时,会触发删除失败
<script>
var person = {}
person.name = 'kyo'
person.age = 20
//添加只读属性
Object.defineProperty(person,'id',{
value: 1,
writable: false
})
console.log(delete person.age) //true
console.log(delete person.friend) //true
console.log(delete person.id) //false
console.log(person) //{name: 'kyo', id: 1}
</script>
3.改(修改字段值)
<script>
var person = {
name: 'kyo',
age: 20
}
person.age = 21
console.log(person) //{name: 'kyo', age: 21}
</script>
4.查
- 可枚举:通过字面量方式添加的属性都是可枚举的,只有Object.defineProperty()方式添加的才有不可枚举的可能性,涉及遍历的方法,都只能遍历可枚举的属性,后面不再标注
- 属性遍历:使用 for in 对属性名称进行遍历
<script>
var person = {}
person.name = 'kyo'
person.age = 20
//添加属性(默认不可枚举)
Object.defineProperty(person,'id',{
value: 1,
})
//遍历(id属性不可枚举,遍历时会被忽略)
for(var key in person){
console.log(key)
//name
//age
}
</script>
- 获取属性名列表:Object.keys() - 将对象属性组合成数组返回
<script>
var person = {}
person.name = 'kyo'
person.age = 20
//添加属性(默认不可枚举)
Object.defineProperty(person,'id',{
value: 1,
})
//属性名列表
var keys = Object.keys(person)
console.log(keys) // ['name', 'age']
</script>
- 获取属性值列表:Object.values() - 将对象属性值组合成数组返回
<script>
var person = {}
person.name = 'kyo'
person.age = 20
//添加属性(默认不可枚举)
Object.defineProperty(person,'id',{
value: 1,
})
//属性名列表
var keys = Object.values(person)
console.log(keys) // ['kyo', 20]
</script>
- 获取属性和属性值列表:Object.entries() - 将对象转换成二维数组返回,及 [[key1,value1],[key2,value2]]
<script>
var person = {}
person.name = 'kyo'
person.age = 20
//添加属性(默认不可枚举)
Object.defineProperty(person,'id',{
value: 1,
})
//
var result = Object.entries(person)
console.log(result) // [['name', 'kyo'],['age', 20]]
</script>
- 判断自身属性:hasOwnProperty(key) / in 运算符 原型链上的不算
<script>
var person = {}
person.name = 'kyo'
person.age = 20
//添加属性(默认不可枚举)
Object.defineProperty(person,'id',{
value: 1,
})
//枚举与非枚举属性都支持
console.log(person.hasOwnProperty('name')) //true
console.log(person.hasOwnProperty('id')) //true
//原型链属性不支持
console.log(person.hasOwnProperty) //hasOwnProperty() { [native code] }
console.log(person.hasOwnProperty('hasOwnProperty')) //false
'name' in person //true
</script>
- 获取属性名列表2:Object.getOwnPropertyNames - 相当于Object.keys()的加强版,能遍历不可枚举属性
<script>
var person = {}
person.name = 'kyo'
person.age = 20
//添加属性(默认不可枚举)
Object.defineProperty(person,'id',{
value: 1,
})
var keys = Object.getOwnPropertyNames(person)
console.log(keys) //['name', 'age', 'id']
</script>
5.对象属性值合并
- 将一个或多个对象的键值对合并到目标对象中并将目标对象返回:Object.assign(target, ...sources) 执行完毕后,target会被改变
- 注意:操作完成后,target会被改变,如果有同名字段,则会被后面的对象覆盖
<script>
//人员1
var person = {
name: 'key',
age: 20
}
//技能1
var skill_1 = {
html: "熟练",
js: "熟练"
}
//技能2
var skill_2 = {
php: "空白",
database: "空白",
//有冲突的字段
age: 25
}
//合并
console.log(Object.assign(person,skill_1,skill_2)) //{name: 'key', age: 25, html: '熟练', js: '熟练', php: '空白', …}
//原对象
console.log(person) //{name: 'key', age: 25, html: '熟练', js: '熟练', php: '空白', …}
console.log(skill_1) //{html: '熟练', js: '熟练'}
console.log(skill_2) //{php: '空白', database: '空白'}
</script>
6.空对象
- 对象的非空验证思路很简单,遍历其属性名即可,存在一个或者一个以上的属性名,就表示不为空
<script>
function ObjIsEmpty(obj){
var isEmpty = true
//如果存在任何一个属性,则将isEmpty赋值为false
for(key in obj){
isEmpty = false
}
return isEmpty
}
var obj = {}
var obj2 = {a:1, b:2}
console.log(ObjIsEmpty(obj)) //true
console.log(ObjIsEmpty(obj2)) //false
</script>
7.转换成JSON字符串
- 通过JSON.stringify()可将对象转换成JSON字符串
<script>
var obj = {}
var obj2 = {a:1, b:2}
console.log(JSON.stringify(obj)) //{}
console.log(JSON.stringify(obj2)) //{a:1, b:2}
</script>
- 通过JSON.parse()可将JSON字符串转换成对象
<script>
var objStr = '{"a":1, "b":2}'
var obj = JSON.parse(objStr)
console.log(obj.a,obj.b) //1 2
</script>
8.数据代理与数据劫持
- 数据劫持:通过Object.defineProperty()方法给对象添加字段,就可以监听字段的读取与修改
- 数据代理:数据劫持过程中的set方法不能操作自身的字段值,会造成死循环,所以数据劫持时只能操作第三方的数据,称之为 数据代理
<script>
//数据代理源
var vm = {}
//原始数据(用作缓存)
var data = {
name: "张飒",
age: 20
}
//给代理源添加字段并监听
Object.defineProperty(vm,'name',{
configurable: false, // 不可重定义
enumerable: true, // 可枚举 该属性名能被Object.keys()获取
get(){
return data.name
},
set(newVal){
console.log('name 值发生变动,请修改页面对应的元素',)
data.name = newVal
}
})
//给代理源添加字段并监听
Object.defineProperty(vm,'age',{
configurable: false, // 不可重定义
enumerable: true, // 可枚举 该属性名能被Object.keys()获取
get(){
return data.age
},
set(newVal){
console.log('age 值发生变动,请修改页面对应的元素',)
data.age = newVal
}
})
console.log(vm.name,vm.age)
vm.name = "李四" //打印 name 值发生变动,请修改页面对应的元素
console.log(vm.name,vm.age)
</script>
9.对象拷贝
<script>
//构造函数
function Person(name,age){
this.name = name
this.age = age
}
//原型链方法
Person.prototype.sayHello = function(){
console.log(`我的名字是${this.name},今年${this.age}岁`)
}
//以下代码,你只能操作p1,不能操作Person
//创建实例
var p1 = new Person("张三",20)
//拷贝这个对象(这个方式只能拷贝属性,无法拷贝不可枚举属性和原型)
var p2 = JSON.parse(JSON.stringify(p1))
//拷贝实例的属性和原型
function copyObject(obj){
//获取传入实例的原型
var orig_Prototype = Object.getPrototypeOf(obj)
//创建一个指向实例原型的对象(传入实例的原型)
var new_obj = Object.create(orig_Prototype)
//遍历自身属性(包括不可枚举属性),循环挂载
Object.getOwnPropertyNames(obj).forEach((propKey)=>{
//获取属性描述
var desc = Object.getOwnPropertyDescriptor(obj, propKey)
//挂载属性
Object.defineProperty(new_obj, propKey, desc)
})
//返回结果
return new_obj
}
//调用
var p3 = copyObject(p1)
//成功调用原型链方法
p3.sayHello() //我的名字是张三,今年20岁
//构造函数一致
console.log(p3.constructor) //=> Person
</script>