9.对象的扩展
1.属性的简洁表示法
es6允许直接写入变量和函数,作为对象的属性和方法--为了简洁
2.属性名表达式
字面量定义对象,除es5中的标识符定义属性外,es6新增 表达式放到方括号内 来作为对象的属性名/方法名。
注意:
3.方法的name属性
函数的name属性,返回函数名。对象方法也是函数,因此也有name属性。
注意点:
1.使用了取值函数(getter)和存值函数(setter),会在name前加上‘get/set’
2.特殊情况1:bind方法创造的函数,name属性返回bound加上原函数的名字
3.特殊情况2:如果对象的方法是一个 Symbol 值,那么name属性返回的是这个 Symbol 值的描述
4.Object.is()
用于比较两个值是否严格相等;弥补===的两个缺陷:
1)+0===-0 //true
2)NaN===NaN //false
5.Object.assign()
用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target);例如:Object.assign(target,source1,source2);
特点:
1)若出现同名属性,则后面的属性会覆盖前面的属性
2)Object.assign(obj)===obj // true
如果只有一个参数,Object.assign会直接返回该参数。
3)
4)source无法转换成对象(null,undefined),则会被跳过处理;
其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。
5)Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)
6)属性名为 Symbol 值的属性,也会被Object.assign拷贝
Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' })
// { a: 'b', Symbol(c): 'd' }
注意点:
1)浅拷贝
如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用
2)同名属性是替换而非添加
3)数组的处理
4)取值函数的处理
Object.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制
Object.assign()方法的常见用途:
1)为对象添加属性
2)为对象添加方法
3)克隆对象
4)合并多个对象
5)为属性指定默认值
6.属性的可枚举性和遍历
可枚举性
描述对象的enumerable属性,称为”可枚举性“,如果该属性为false,就表示某些操作会忽略当前属性。
目前,有四个操作会忽略enumerable为false的属性。
for...in循环:只遍历对象自身的和继承的可枚举的属性。
Object.keys():返回对象自身的所有可枚举的属性的键名。
JSON.stringify():只串行化对象自身的可枚举的属性。
Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的属性。所以,尽量不要用for...in循环,而用Object.keys()代替。
遍历
es6的5种方法遍历属性:
1)for...in
2)Object.keys()
3)Object.ownKeys()
4)Object.getOwnPropertyNames(obj)
5)Object.getOwnPropertySymbols(obj)
以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
首先遍历所有数值键,按照数值升序排列。
其次遍历所有字符串键,按照加入时间升序排列。
最后遍历所有 Symbol 键,按照加入时间升序排列。
7.Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptor方法会返回某个对象属性的描述对象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors方法,返回指定对象所有自身属性(非继承属性)的描述对象
8.原型链对象的操作方法:__proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()
(1)__proto__属性:
读取或设置当前对象的prototype对象(原型对象)
标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。
无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替
实现上,__proto__调用的是Object.prototype.__proto__
(2)Object.setPrototypeOf()
用来设置一个对象的prototype对象,返回参数对象本身(ES6 正式推荐的设置原型对象的方法)
注意:
1)第一个参数不是对象时,会自动转成对象,但方法返回的时第一个参数本身,所以不会有变化
2)若第一个参数是undefined或null,无法转成对象,则会报错
(3)Object.getPrototypeOf()
用来读取对象的prototype对象 格式:Object.getPrototypeOf(obj)
注意点同Object.setPrototypeOf()
9.super关键字
this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象
JavaScript 引擎内部,super.foo等同于Object.getPrototypeOf(this).foo(属性)或Object.getPrototypeOf(this).foo.call(this)(方法)。
10.Object.keys(),Object.values(),Object.entries()--键,值,键值对
Object.keys():ES5中引入的,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名;
后两个方法也是不含继承的,可遍历的;返回数组的成员顺序,与本章的《属性的遍历》部分介绍的排列规则一致
ES2017 引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for...of循环使用。
11.对象的扩展运算符...
ES2017 将这个运算符引入了对象; 和数组的扩展运算符很相似
用于:(1)解构赋值--扩展运算符的解构赋值,不能复制继承自原型对象的属性
(2)扩展运算符--用于取出参数对象的所有可遍历属性,拷贝到当前对象之中