1.属性的简洁表示法

const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"} // 等同于
const baz = {foo: foo};

ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。

let birth ='2000/01/01';
const Person={
name:'张三',
//等同于birth: birth
birth,
// 等同于hello: function ()...
hello(){ console.log('我的名字是', this.name); }
};

2.属性名的表达式

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"

ES6 允许字面量定义对象时,用(表达式)作为对象的属性名,即把表达式放在方括号内。

注意,属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object],这一点要特别小心。

const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
[keyA]: 'valueA',
[keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}

3.属性的遍历

ES6 一共有 5 种方法可以遍历对象的属性。

(1)for...in

for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

(2)Object.keys(obj)

Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

(3)Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

(4)Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

(5)Reflect.ownKeys(obj)

Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

  • 首先遍历所有数值键,按照数值升序排列。
  • 其次遍历所有字符串键,按照加入时间升序排列。
  • 最后遍历所有 Symbol 键,按照加入时间升序排列。
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]

上面代码中,Reflect.ownKeys方法返回一个数组,包含了参数对象的所有属性。这个数组的属性次序是这样的,首先是数值属性210,其次是字符串属性ba,最后是 Symbol 属性。

4.对象的扩展运算符

(1)解构赋值

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }

上面代码中,变量z是解构赋值所在的对象。它获取等号右边的所有尚未读取的键(ab),将它们连同值一起拷贝过来。

由于解构赋值要求等号右边是一个对象,所以如果等号右边是undefinednull,就会报错,因为它们无法转为对象。

let { ...z } = null; // 运行时错误
let { ...z } = undefined; // 运行时错误

解构赋值必须是最后一个参数,否则会报错。

let { ...x, y, z } = someObject; // 句法错误
let { x, ...y, ...z } = someObject; // 句法错误

解构赋值的一个用处,是扩展某个函数的参数,引入其他操作。

function baseFunction({ a, b }) {
// ...
}
function wrapperFunction({ x, y, ...restConfig }) {
// 使用 x 和 y 参数进行操作
// 其余参数传给原始函数
return baseFunction(restConfig);
}

(2)扩展运算符

let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }

由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组。

let foo = { ...['a', 'b', 'c'] };
foo
// {0: "a", 1: "b", 2: "c"}

扩展运算符可以用于合并两个对象。

let ab = { ...a, ...b };
// 等同于
let ab = Object.assign({}, a, b);

这用来修改现有对象部分的属性就很方便了。

let newVersion = {
...previousVersion,
name: 'New Name' // Override the name property
};

上面代码中,newVersion对象自定义了name属性,其他属性全部复制自previousVersion对象。

与数组的扩展运算符一样,对象的扩展运算符后面可以跟表达式。

const obj = {
...(x > 1 ? {a: 1} : {}),
b: 2,
};

最新文章

  1. 微信企业号 获取AccessToken
  2. POJ2104 K-th Number [分块做法]
  3. JS操作未跨域iframe里的DOM
  4. 牛顿法与拟牛顿法学习笔记(三)DFP 算法
  5. C#学习笔记----.net操作进程
  6. mxnet环境搭建随记
  7. mac攻略(三) -- apache站点配置
  8. vimdiff
  9. vJine 第三波 之 Lua 来袭 vJine.Lua
  10. Struts—自定义一个简单的mystruct
  11. vim 折叠代码技巧汇总
  12. 【网站建设】Linux上安装MySQL - 12条命令搞定MySql
  13. asp.net core 系列 10 配置configuration (上)
  14. mongodb初级
  15. PHP6天基础知识部分
  16. android --------- 嵌套unity出现 your hardware does not support this application,sorry!
  17. mysql的innodb存储引擎和myisam存储引擎的区别
  18. linux 进程guanl管理的常用几个命令
  19. FolderSync Instant sync 即时同步
  20. Java 经典问题

热门文章

  1. VMware虚拟网卡设置问题
  2. 深入学习keepalived之一 keepalived的启动
  3. multiprocessing 模块
  4. C++程序设计基础(3)条件语句和循环语句
  5. 获取全球dns统计信息
  6. 深入理解JavaScript系列(34):设计模式之命令模式
  7. javascript移动端滑屏事件
  8. 通过js操作样式(评分)
  9. js获取客户端用户IP
  10. 集合之Iterator迭代器