- 一组数据和功能的集合
- 创建对象
- var obj = {}
- var obj = new Object()
- 实例obj的原型为Object.prototype,具有如下属性和方法
- constructor:创建当前实例对象的函数
- hasOwnProperty(属性):给定属性是否在当前实例对象中,而不是在实例的原型对象中
- propertyIsEnumerable(属性):给定属性是否可以使用for…in枚举
- isPrototypeOf(object):对象原型是否是当前传入对象的原型
- 原型对象.isPrototypeOf(实例对象)
Object.prototype.isPrototypeOf(obj) // true
- 实例 instanceof 构造函数
obj instanceof Object // true
- toString():返回对象的字符串表示
- toLocalString():返回对象的字符串表示,与当前执行环境的地区对应
- valueOf():返回对象的字符串、数值、布尔值表示
var obj = new Object()
obj.toString() //"[object Object]"
obj.valueOf() //{}
var obj1 = {num:123}
obj1.valueOf() //{num:123}
- 访问对象
- 点:点后面只能接字符串
- []:[]中最终放的是字符串(可以是指向字符串的变量,带空格或关键字等的字符串)
ES6新增
- 对象属性的简洁表示:
- 允许直接写入变量和函数作为对象的属性和方法
- 只写属性名,不写属性值,属性值为属性名所代表的变量
- 属性名为字符串
- 定义对象的属性
- 点:
- []:方括号中可以是变量,表达式,字符串,最终的值都是字符串
- 属性表达式:属性名用[]定义,且里面为表达式形式
let a = 'aa' let keyA = {a:1} let keyB = Symbol('description') function fn(){} let obj = { a, //a:a fn, fn1(){}, //fn1:function(){} ['a'+'b']:'ab', //属性名表达式 [keyA]:'objA', //[object Object]:'objA' [keyB](){}, get foo(){}, set foo(x){} }
- 对象方法的name属性:
- 函数的name属性为函数名
- 对象的方法也是函数,name属性也是该方法函数的函数名
- name获取:
- 对象的普通方法:obj.fn.name
- 对象的get、set方法:Object.getOwnPropertyDescriptor(obj,‘foo’).get.name
- 构造函数:anonymous
- bind:bound
- 方法名为Symbol(‘description’):name为Symbol的描述description
- Object.is(对象1,对象2):
比较两个对象是否相等,类似全等操作符,不同之处为:+0不等于-0,NaN等于自身- Object.assign(target,source1,source2):
- 将源对象自身的(不包括继承的)所有可枚举复制到目标对象
- 目标对象与源对象,或者多个源对象有同名属性时,后面的属性会覆盖前面的
- 只有一个参数时,会直接返回该参数对象,改参数不是对象时会先转为对象
- undefined、null不能转为对象,不能放在第一个参数,否则会报错,放在后面会被跳过,不报错
- 后面的参数为Number、Boolean、String时,只有String会议数组形式(‘abc’ = [‘a’,‘b’,‘c’])复制到目标对象;其他类型值不会产生效果,因为只有字符串的包装类型对象会产生可枚举属性
Object.assign({},‘abc’,true,123) //{‘0’:‘a’,‘1’:‘b’,‘2’:‘c’}- 该方法为浅复制(即属性值为对象时支付至该对象的引用)
- Lodash的_.defaultsDeep()方法可以深复制
- Object.assign()处理数组时,会把数组看成对象,属性行为0,1,2的对象
Object.assign([1,2,3],[4,5]) //[4,5,3]- 用途:
复制对象
合并多个对象
为对象添加属性和方法
为属性指定默认值(根据后面参数的属性会覆盖前面的,属性值不能为对象,会删除某些属性)//第三个对象的url会覆盖def对象的url,导致host属性被删除 let def = { url:{ host:xxx.com, port:1000 } } Object.assign({},def,{url:{port:1001}}) //如下代码是可以的 let def = { host:xxx.com, port:1000 } Object.assign({},def,{port:1001})
- 对象属性的描述对象
- 描述对象:对象的每个属性都有一个描述对象,用来控制该属性的行为
>2. 获取对象属性的描述对象 Object.getOwnPropertyDescriptor(obj,属性) { value:123, writable:true, enumerable:true, configurable:true } >3. 获取指定对象自身的所有属性的描述对象 Object.getOwnPropertyDescriptors(obj) let obj = { foo:123, get bar(){} } {foo: { value:123, writable:true, enumerable:true, configurable:true }, bar: { get:[Function:bar], set:undefined, enumerable:true, configurable:true } }
解决Object.assign()无法复制get、set属性的问题,可以使用Object.getOwnPropertyDescriptors(obj)和Object.defineProperties()实现
const source = {
set foo(value){}
}
const target = {}
/*获取不到set方法
Object.assign(target,source)
Object.getOwnPropertyDescriptor(target,'foo')
{ //数据属性
value:undefined, //assign只会复制一个值,不会复制值背后的赋值或取值方法
writable:true,
enumerable:true,
configurable:true
}*/
//可以获取到set
Object.defineProperties(target,Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target,'foo')
{ //访问器属性
get:undefined,
set:[Function:foo],
enumerable:true,
configurable:true
}
- 忽略不可枚举属性的操作:
for…in
Object.keys()
Object.assign()
JSON.stringify()
Class的原型的方法
除了for…in为包含自身和继承属性,其他都是自身的
- 对象属性的遍历
- for…in:包含对象自身和继承的所有可枚举属性(不包含Symbol属性)
- Object.keys(obj):包含对象自身的所有可枚举属性(不包含Symbol属性),返回一个数组
- Object.getOwnPropertyNames(obj):包含对象自身的所有属性(不包含Symbol属性),返回一个数组
- Object.getOwnPropertySymbols(obj):包含对象自身的所有Symbol属性,返回一个数组
- Reflect.ownKeys(obj):包含对象自身的所有属性(包含Symbol属性,是否可枚举),返回一个数组
- 遍历顺序:
1)所有属性名为数值的属性,按数字排序
2)所有属性名为字符串的属性,按生成时间排序
3)所有属性名为Symbol的属性,按生成时间排序
- 获取和设置对象的原型对象
- 获取:
Object.getPrototypeOf(obj,prototype)- 设置:设置指定对象obj的原型对象为prototype对象,代替obj.proto = prototype
Object.setPrototypeOf(obj)
- keys()、values()、entries():遍历对象自身的所有可枚举属性,返回数组(一般用于for…of循环)
- Object.keys():返回的数组的成员为属性的键名
- Object.values():返回的数组的成员为属性的键值
- Object.entries():返回的数组的成员为属性的键值对
- Null传导运算符,问号加点?.:
- message.body.user.firstName,要先判断点前面对象(有3个)的不为undefined和null
- 方法一:
let firstName = (message&&message.body&&message.body.user&&message.body.user.firstName)||‘default’- 方法二:
let firstName = message?.body?.user?.firstName||‘default’- 只要前面3个有一个为undefined或null,就不再运算,返回undefined
- 对象的解构赋值和扩展运算符
- 对象的解构赋值:用于从一个对象取值,相当于将多有可遍历的但尚未被读取的属性分配到指定的对象上面,解构赋值为浅复制,只复制自身的不包含继承的
- 对象的扩展运算符:用于去除参数对象的所有可遍历属性,并将其复制到当前对象之中
- let {x,y,…z} = {x:1,y:2,a:3,b:4} //z为{a:3,b:4}
- let obj = {…{a:1,b:2}} //obj为{a:1,b:2}
let obj = …{a:1,b:2} //报错