属性的简介表示法
ES6允许在对象中只写属性名,不写属性值。这是,属性值等于属性名所代表的变量。
function f(x, y){ return {x, y}};
等价于 function f(x, y){ return {x: x, y: y}};
·除了属性,方法也可以简写
var o = {method() {.....}}
等价于 var o = {method: function(){......}}
属性名表达式
方法一
obj.foo = true;
方法二
obj[‘a’ + ‘bc’] = 123;
ES6允许字面量定义对象时用方法二(表达式作为对象属性名),即把表达式放在方括号内。
列子:
let propKey = ‘foo’;
let obj = {[propKey ]:true,[‘a’ + ‘bc’]:123}
表达式还可用于定义方法名
let obj = {
[‘h’ + ‘ello’]() {......}
}
obj.hello();
注:属性表达式与简洁表示法不能同时使用,否则会报错。
属性名表达式如果是一个对象,默认情况下回自动将对象转为字符串[object Object]。
方法的name属性
函数的name属性返回函数名。对象的方法也是函数,因此也有name属性。
特殊情况:bind方法构造的函数,name属性返回”bound”加上原函数的名字;Function构造函数创造的函数,name属性返回”anonymous”。
var doSomething = function(){......}
doSomething.bind().name //’bound doSomething’
如果对象的方法是一个Symbol值,那么name属性返回的是这个Symbol值的描述。
const key1 = Symbol(“description”);
const key2 = Symbol();
let obj = { [key1]() {}, [key2]() {}};
obj[key1].name //’description’
obj[key2].name //’’
Object.is()
比较两个值是否相等
ES5
+0 === -0 //true
NaN === NaN //false
ES6
Object.is(+0, -0) //false
Object.is(NaN , NaN ) //true
Object.assign()
用于将源对象(source)的所有可枚举属性复制到目标对象(target)。
var target = [ a: 1, b: 2];
var source1= [ b: 4, c: 5];
var source2= [ a: 7, c: 8];
Object.assign(target ,source1,source2); //{a: 7, b: 4, c: 8}
如果目标对象与源对象有同属性名,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
Object.assign方法是浅复制而不是深复制
应用:
为对象添加属性
为对象添加方法
Object.assign(SomeClass.prototype,{
someMethod(arg1,arg2) {......},
anotherMethod(arg1,arg2) {......}
});
等价于:
SomeClass.prototype.someMethod(arg1,arg2) {......};
SomeClass.prototype.anotherMethod(arg1,arg2) {......};
克隆对象
function clone(origin) {
return Object.assign({}, origin);
}
合并多个对象
const merge = (...sorces) => Object.assign({}, ...sorces);
为属性指定默认值
const DEFAULLS = {logLevel: 0,outputFormat: ’html’}; //存放默认值
function processContent(options){
options = Object.assign({}, DEFAULLS, options);
}
属性的可枚举性
对象的每一个属性都具有一个描述对象(descriptor),用于描述该属性的行为。
Object.getOwnPrototypeDescriptor方法可以回去该属性的描述对象。
let obj = { foo: 123};
Object.getOwnPrototypeDescriptor(obj, foo);
// {
// value:123, 值
// writable: true, 是否可写
// enumerable: true, 是否可枚举
// configurable: true 是否可配置
//}
属性的遍历
- for ... in
- Object.keys(obj)
- Object.getOwnPrototypeName(obj)
- Object.getOwnPrototypeSymbols(obj)
- Reflect.ownKeys(obj)
__proto__属性、Object.setPrototypeOf()、Object.getPrototypeOf()
- _proto_属性
用来读取或设置当前对象的prototype对象
ES5写法
var obj = Object.create(someOtherObj);
obj.method = function(){......};
ES6写法
var obj = {
method: function(){......}
}
obj ._proto_ = someOtherObj;
Object.setPrototypeOf()
作用与_proto_相同,用来设置一个对象的prototype对象,返回参数对象本身。它是ES6正式推荐的设置原型对象的方法。
例子:
let proto = {};
let obj = { x :10 };
Object.setPrototypeOf(obj, proto);
proto.y = 20;
proto.z = 40;
obj // {x : 10, y: 20, z:40}
Object.getPrototypeOf()
该方法与setPrototypeOf()方法配套,用于读取一个对象的prototype对象。
Object.keys()、Object.values()、Object.entries()
Object.keys()
返回一个数组,成员是参数对象自身的(不包含继承的)所有可遍历(enumerable)属性的键名。
Object.values()
返回一个数组,成员是参数对象自身的(不包含继承的)所有可遍历(enumerable)属性的键值。
Object.entries()
返回一个数组,成员是参数对象自身的(不包含继承的)所有可遍历(enumerable)属性的键值对数组。
对象的扩展运算符
解构赋值
用于从一个对象取值,相当于将所有可遍历的、但尚未被读取的属性分配到指定的对象上面。所有的键和他们的值都会赋值到新的对象上面。
Let { x, y, ...z} = { x: 1, y: 2, a: 3, b: 4 }
//x = 1; y = 2; z = {a: 3, b: 4 }
右边是undefined或null就会报错。
解构赋值必须是最后一个参数,否则会报错。
解构赋值是浅复制,即如果一个键的值是符合类型的值(数组、对象、函数),那么解构赋值复制的是这个值的引用,而不是这个值的副本。
扩展运算符
用于取参数对象的所有可遍历属性,并将其复制到当前对象之中
let aClone = { ...a};
等价于 let aClone = Object.assign({}, a);
上面的例子只是复制了对象实例的属性,如果想完整克隆一个对象,还要复制对象原型的属性,可采用以下方法:
const clone = {
Object.create(Object.getPrototypeOf(obj));
...obj
}
扩展运算符可合并两个对象
let ab = {...a, ...b};
等价于 Object.assign({}, a, b);
Object.getOwnPropertyDescripors()
返回指定对象所有自身属性(非继承属性)的描述对象。
Null传导运算符
如果读取对象内部的某个属性,往往需要判断该对象是否存在。
ES5写法
const firstname = (message && message.body && message.body.firstname ) || ‘default’
ES6写法
const firstname = message?.body?.firstname || ‘default’
只要其中一个?.返回Null或undefined,就不再继续运行。
4中用法:
obj?.prop:读取对象属性
obj?.[expr]:同上
Func?.(...args):函数或对象方法的调用
New C?.(...args):构造函数的调用