乐趣区

ES6对象的扩展及新增方法。

1. 属性的简洁表示法
ES6 允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
const foo = ‘bar’;
const baz = {foo};
baz//{foo:’bar’}

// 等同于
const baz = {foo:foo}
上面代码表明,ES6 允许在对象之中,直接写变量。这时,属性名为变量名,属性值为变量的值。下面是另一个例子。
function f(x,y){
return {x,y}
}
// 等同于
function f(x,y){
return {x:x,y:y};
}
f(1,2)//{x:1,y:2}
除了属性简写,方法也可以简写。
const o ={
method(){
return ‘Hello!’
}
}
// 等同于
const o = {
method:function(){
return ‘Hellow’;
}
}
下面是一个实际的例子。
let birth = ‘2000/01/01′;
const Person ={
name:’ 张三 ’,
// 等同于 birth:birth
birth,
// 等同于 hello :function()….
hello(){
console.log(‘ 我的名字是 ’,this.name)
}
}
这种写法用于函数的返回值,将会非常方便。
function getPoint(){
const x =1;
const y = 10;
return {x,y}
}
getPoint()//{x:1,y:10}
CommonJS 模块输出一组变量,就非常合适使用简洁写法。
let ms = {};
function getItem(key){
return key in ms ?ms[key]:null;
}
function setItem(key,value){
ms[key] = value;
}
function clear(){
ms={}
}
module.exports = {getItem,setItem,clear};
// 等同于
module.exports = {
getItem:getItem,
setItem:setItem,
clearLclear
}
属性的赋值器 (setter) 和取值器(getter), 事实上也是采用这种写法。
const cart = {
_wheels:4,
get wheels(){
return this._wheels;
},
set wheels (value){
if(value<this._wheels){
throw new Error(‘ 数值太小了!’);
}
this._whells = value;
}
}
2. 属性名表达式
JavaScript 定义对象的属性,有两种方法。
// 方法一
obj.foo = true;
// 方法二
obj[‘a’+’bc’] = 123;
上面代码的方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时将表达式放在方括号之内。但是,如果使用字面量定义对象 (使用大括号),在 ES5 中只能使用方法一(标识符) 定义属性。
var obj ={
foo:true,
abc:123
}
ES6 允许字面量定义对象时,用方法二作为对象的属性名,即把表达式放在括号内。
let propKey = ‘foo’;
let obj ={
[propKey]:true,
[‘a’+’bc’]:123
}
下面是另一个例子:
let lastWord = ‘last word’;
const a = {
‘first word’:’hello’,
[lastWord]:’world’
};
a[‘first word’]//hello
a[lastWord]//world
a[‘last word’]//world
表达式还可以用于定义方法名。
let obj = {
[‘h’+’ello’](){
return ‘hi’
}
}
obj.hello()//hi;
注意:
属性名表达式与简洁表示法,不能同时使用,会报错。
属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object object], 这一点要特别小心。
const keyA = {a:1};
const keyB = {b:2};
const myObject = {
[keyA]:’valueA’,
[keyB]:’valueB’
};
myObject;// Object {[object Object]: “valueB”}
上面代码中,[keyA]和 [keyB] 得到的都是 [object object], 所以[keyB] 会把 [keyA] 覆盖掉,而 myObject 最后只有一个 [object object] 属性。
方法的 name 属性
函数的 name 属性,返回函数名。对象方法也是函数,因此也有 name 属性。
const person = {
sayName() {
console.log(‘hello!’);
},
};

person.sayName.name // “sayName”
属性的可枚举型和遍历
对象的每个属性都有一个描述对象,用来控制改属性的行为。Object.getOwnPropertyDescriptor(obj,’foo’)方法可以获取该属性的描述对象。描述对象的 enumerable 属性,称为可枚举性,如果该属性为 false,就表示某些操作会忽略当前的属性。目前,有四个操作会忽略 enumerable 为 false 的属性。
for…in 循环:只遍历对象自身的和继承的可枚举的属性。(不包含 Symbol 属性)
Object.keys(): 返回对象自身的所有可枚举的属性的键名, 返回一个数组。(不包含 Symbol)
JSON.stringify(): 只串行化对象自身的可枚举的属性。
object.assign(): 忽略 enumrable 为 false 的属性,只拷贝对象自身的可枚举的属性。

ES6 一共有 5 种方法可以遍历对象的属性。(1)for…in
for…in 循环遍历对象自身的和继承的可枚举属性(不包含 Symbol 属性)。
(2)Object.keys(obj)
object.keys 返回一个数组,包含对象自身的(不含继承的)所有可枚举属性(不包含 Symbol 属性)的键名。
(3)Object.getOwnPropertyNames(obj)
返回一个数组,包含对象自身的所有属性 (不含 Symbol 属性,但是包括不可枚举属性) 的键名。
(4)Object.getOwnPropertySymbols(obj)
返回一个数组,包含对象自身的所有 Symbol 属性的键名。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys 返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

super 关键字
我们知道,this 关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字 super,指向当前对象的原型对象。
const proto = {
foo:’hello’
};
const obj = {
foo:’world’,
find(){
return super.foo;
}
};
Object.setPrototypeOf(obj,proto);
obj.find();//hello
上面代码中,对象 obj.find()方法之中,通过 super.foo 引用了原型对象 proto 的 foo 属性。注意:super 关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。目前,只有对象方法的简写法可以让 Javascript 引擎确认,定义的是对象的方法。JavaScript 引擎内部,super.foo 等同于 Object.getPrototypeOf(this).foo 或 Object.getPrototypeOf(this).foo.call(this)。
对象的扩展运算符
解构赋值对象的解构赋值用于从一个对象取值,相当于将目标对象自身的所有可遍历、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。
let{x,y,…z} = {x:1,y:2,a:3,b;4};
x//1,
y//2,
z//{a:3,b:4}
上面代码中,变量 z 是解构赋值所在的对象。它获取等号右边的所有尚未读取的键(a 和 b), 将它们连同值一起拷贝过来。

退出移动版