es6学习笔记3--解构和对象
2016-07-15 14:52
253 查看
1、解构
在接收数据的地方(比如赋值的左边),解构使你使用模式去获取部分数据。下面的代码是解构的一个例子:
let obj = { first: 'Jane', last: 'Doe' }; let { first: f, last: l } = obj; // (A) // f = 'Jane'; l = 'Doe'
在行 A 解构了
obj:通过左边的模式,运用赋值操作符(=)从里面获取数据,并将数据赋值给变量
f和
l。这些变量事先自动声明好,因为该行以
let开始。
也可以解构数组:
let [x, y] = ['a', 'b']; // x = 'a'; y = 'b'
解构可以用于下列情形:
// Variable declarations:解构赋值不仅适用于var命令,也适用于let和const命令。 let [x] = ['a']; const [x] = ['a']; var [x] = ['a']; // Assignments: [x] = ['a']; // Parameter definitions: function f([x]) { ··· } f(['a']);
也可以在一个
for-of循环中解构:
// Handled like a variable declaration: for (let [k,v] of arr.entries()) ··· // Handled like an assignment for ({name: n, age: a} of arr) ···
(1)Rest解构赋值
对象的Rest解构赋值用于从一个对象取值,相当于将所有可遍历的、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; x // 1 y // 2 z // { a: 3, b: 4 }
上面代码中,变量
z是Rest解构赋值所在的对象。它获取等号右边的所有尚未读取的键(
a和
b),将它们和它们的值拷贝过来。
由于Rest解构赋值要求等号右边是一个对象,所以如果等号右边是
undefined或
null,就会报错,因为它们无法转为对象。
let { x, y, ...z } = null; // 运行时错误 let { x, y, ...z } = undefined; // 运行时错误
Rest解构赋值必须是最后一个参数,否则会报错。
let { ...x, y, z } = obj; // 句法错误 let { x, ...y, ...z } = obj; // 句法错误
上面代码中,Rest解构赋值不是最后一个参数,所以会报错。
圆括号问题
解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。由此带来的问题是,如果模式中出现圆括号怎么处理。ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号。
变量声明语句中,不能带有圆括号。
函数参数中,模式不能带有圆括号。
赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中。
用途:
交换变量的值从函数返回多个值
函数参数的定义
提取JSON数据
函数参数的默认值
遍历Map结构
输入模块的指定方法
总结:
如果解构不成功,变量的值就等于
undefined。
不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
解构赋值允许指定默认值。
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
默认值生效的条件是,对象的属性值严格等于
undefined。
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。由于
undefined和
null无法转为对象,所以对它们进行解构赋值,都会报错。
2、新的对象字面量特性
1、新的对象字面量特性
方法定义:let obj = { myMethod(x, y) { ··· } };
属性值缩写:
let first = 'Jane'; let last = 'Doe'; let obj = { first, last }; // Same as: let obj = { first: first, last: last };
计算属性键:
let propKey = 'foo'; let obj = { [propKey]: true, ['b'+'ar']: 123 };
这种新语法也可用于方法定义:
let obj = { ['h'+'ello']() { return 'hi'; } }; console.log(obj.hello()); // hi
计算属性键主要的应用场景就是使 symbol 成为属性键变得更加方便。
2、Object
中的新方法
Object中最重要的新方法是
assign()。习惯上,在 JavaScript 的世界中,这个函数叫做
extend()。
Object.assign()仅考虑自有(非继承)属性。
let obj = { foo: 123 }; Object.assign(obj, { bar: true }); console.log(JSON.stringify(obj)); // {"foo":123,"bar":true}
常见用途:
(1)为对象添加属性
(2)为对象添加方法
(3)克隆对象
(4)合并多个对象
(5)为属性指定默认值
属性的遍历
ES6一共有6种方法可以遍历对象的属性。(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或字符串,也不管是否可枚举。
(6)Reflect.enumerate(obj)
Reflect.enumerate返回一个Iterator对象,遍历对象自身的和继承的所有可枚举属性(不含Symbol属性),与
for...in循环相同。
以上的6种方法遍历对象的属性,都遵守同样的属性遍历的次序规则。
首先遍历所有属性名为数值的属性,按照数字排序。
其次遍历所有属性名为字符串的属性,按照生成时间排序。
最后遍历所有属性名为Symbol值的属性,按照生成时间排序。
注意,语言规范把索引定义为字符串键,当转换成无符号整数然后再转换回来,仍然是同样的字符串(同样也必须比232-1小,因此数组是有长度限制的)。这意味着规范把数组索引看作字符串键,甚至普通的对象都可以有数组索引:
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 }) //['2', '10', 'b', 'a', Symbol()]
__proto__
属性,Object.setPrototypeOf(),Object.getPrototypeOf()
(1)__proto__属性
__proto__属性(前后各两个下划线),用来读取或设置当前对象的
prototype对象。目前,所有浏览器(包括IE11)都部署了这个属性。
在实现上,
__proto__调用的是
Object.prototype.__proto__。
(2)Object.setPrototypeOf()
Object.setPrototypeOf方法的作用与
__proto__相同,用来设置一个对象的
prototype对象。它是ES6正式推荐的设置原型对象的方法。
// 格式 Object.setPrototypeOf(object, prototype) // 用法 var o = Object.setPrototypeOf({}, null);
该方法等同于下面的函数。
function (obj, proto) { obj.__proto__ = proto; return obj; }
(3)Object.getPrototypeOf()
该方法与setPrototypeOf方法配套,用于读取一个对象的prototype对象。
Object.values(),Object.entries()
Object.keys()
ES5引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
Object.values()
Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
Object.entries
Object.entries方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
相关文章推荐
- php webservice 可能存在的坑
- jzoj 1577. 【普及模拟】抓猫
- Android Studio Gradle Build Running 特别慢的问题
- K-means聚类算法
- 为什么
- bond安装
- 对js闭包的理解
- PHP静态变量和全局变量的区别
- Eclipse快捷键 10个最有用的快捷键
- 贝叶斯分类器学习笔记
- windows android studio 编译Jni动态库
- Nova 组件详解 - 每天5分钟玩转 OpenStack(26)
- OpenStack 通用设计思路 - 每天5分钟玩转 OpenStack(25)
- Strategy 策略模式
- AsyncTask的使用和源码分析
- Android App的设计架构:MVC,MVP,MVVM与架构经验谈
- Ubuntu系统下android开发环境配置
- List,Map和Set的区别
- 洛谷 P1541 乌龟棋
- 有界面(Activity或其他View)的SDK项目混淆发布