ES6 出来已经很多年了, 最近有点时间, 就顺便总结一下 ES6 的语法特性. 知识多回归感觉还是不一样的, 俗话说:"温故而知新, 可以为师矣". 现在就来温故一下~
1.let 与 const
let 用来声明变量, 并且会在当前作用域形成代码块.
conts 用来声明常量, 所谓常量就是物理指针不可以更改的变量
对于不变的常量都用 const, 如: const PI = 3.14159;
对于当前作用域下的变量要用 let, 如:
- {
- let num = 1;
- }
在这里顺便提一下 let 和 const 都是块作用域, 在作用域之外输出是会报错的, 如:
- {
- let em = 1;
- }
- console.log(em); // ReferenceError
const 除了不变的特性外其余的都跟 let 一样, 但 const 还是可以这样用的, 如:
- const arr = [];
- arr.push('hello is me'); // 这也是可以的
顺便提一下语法规范, 用 const 的时候记得和 let 隔开一行, 如:
- const P = 89451;
- let a = 1,
- b = 2,
- c = 3; // 建议这样书写, 看起来会好很多
2. 字符串
e6 为我们提供了模板字符串, 这个特性很大的方便了我们的一些日常需求, 以前我们拼接字符串的时候都是
- let me,
- str = 'hello' + 'is' + me;
现在你可以这样写
- let me,
- str = hello is ${
- me
- }; // 完美, nice
3. 数组
Array.from
Array.from 可以将两类对象转为真正的数组, 类似数组的对象 (array-like object) 和可遍历 (iterable) 的对象(包括 ES6 新增的数据结构 Set 和 Map, 他们都部署了 iterator 接口, 字符串等), 如:
- let ob = {
- '0': 'a',
- '1': 'b',
- length: 2
- };
- // ES5
- let arrs = [].slice.call(ob);
- console.log(arrs); // ['a', 'b']
- // ES6
- let arrs = Array.from(ob);
- console.log(arrs); // ['a', 'b']
还可以这样
Array.from('arrs'); // ['a', 'r', 'r', 's']
Array.from 也接受第二个参数, 作用就相当于遍历整个数组对每一项值做出相应的操作, 并返回原数组, 如:
- console.log(Array.from([1, 2, 3], arr => arr+1)); //[2, 3, 4];
- Array.of
Array.of() 方法创建一个具有可变数量参数的新数组实例, 而不考虑参数的数量或类型.
Array.of() 和 Array 构造函数之间的区别在于处理整数参数: Array.of(7) 创建一个具有单个元素 7 的数组, 而 Array(7) 创建一个长度为 7 的空数组(注意: 这是指一个有 7 个空位的数组, 而不是由 7 个 undefined 组成的数组), 如:
- Array.of(7); // [7]
- Array.of(1, 2, 3); // [1, 2, 3]
- Array(7); // [ , , , , , , ]
- Array(1, 2, 3); // [1, 2, 3]
find()与 findIndex()
find() 方法返回数组中满足提供的测试函数的第一个元素的值. 否则返回 undefined.
- let arrs = [5, 12, 8, 130, 44];
- let sum = arrs.find(e => e> 10);
- console.log(sum);// 12
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引. 否则返回 - 1.
- let arrs = [5, 12, 8, 130, 44];
- function findFirstLargeNumber(element) {
- return element> 13;
- }
- console.log(arrs.findIndex(findFirstLargeNumber)); //3
扩展运算符
- let arr = [1, 2, 3, 4, 5, 6], arr1;
- arr1 = [ ...arr ]; //[1, 2, 3, 4, 5, 6]
- let arr3 = [1,2,3];
- let arr4 = [0, ...arr3, 4]; // [0,1,2,3,4]
- includes()
includes() 方法用来判断一个数组是否包含一个指定的值, 根据情况, 如果包含则返回 true, 否则返回 false.
- let arrs = [1, 2, 3];
- console.log(arrs.includes(2)); //true
- let pets = ['cat', 'dog', 'bat'];
- console.log(pets.includes('cat')); //true
- console.log(pets.includes('at')); //false
4. 函数
函数传参可赋默认值
- function theFunc( a = 'hello', b = 'es6' ) {
- console.log(a, b);
- }
- theFunc(); //hello es6
- theFunc('study'); //study es6
- theFunc('','test'); //test
参数扩展运算符书写
- function theFunc( ...a ) {
- let sum = a.forEach(row => row + 1);
- console.log(sum);
- }
- theFunc(1,2,3,4); //[2,3,4,5,6]
扩展运算符可以明确指定你需要哪些参数, 并且得到的是一个真实的数组, 而不是 arguments 这样的类数组对象, 如:
- // es5
- function concatenateAll() {
- const args = Array.prototype.slice.call(arguments);
- return args.join('');
- }
- // es6
- function concatenateAll(...args) {
- return args.join('');
- }
箭头函数
箭头函数提供了更简洁的语法, 并且箭头函数中 this 对象的指向是不变的, this 对象绑定定义时所在的对象.
常用写法
let fn= (v=>console.log(v));
箭头函数总是用括号包裹参数, 省略括号只适用于单个参数, 并且还降低了程序的可读性
[1, 2, 3].forEach((x) => x * x);
箭头函数不能用 new
- let Person = (name, age) => {
- this.name = name
- this.age = age
- }
- let p = new Func('TaJie', 25) // error
关于什么时候不能用箭头函数, 可以参考一下这篇文章(链接标题 https://zhuanlan.zhihu.com/p/26540168 ), 这里不多阐述
5. 对象
属性的简洁表示法
ES6 允许直接写入变量和函数, 作为对象的属性和方法. 如:
- const foo = 'bar';
- const baz = {
- foo
- };
- baz // {
- foo: "bar"
- }
- // 等同于
- const baz = {
- foo: foo
- };
除了属性简写, 方法也可以简写. 如:
- let birth = '2000/01/01';
- const Person = {
- name: '张三',
- // 等同于 birth: birth
- birth,
- // 等同于 hello: function ()...
- hello() {
- console.log('我的名字是', this.name);
- }
- };
属性名表达式
ES6 允许字面量定义对象时, 用表达式作为对象的属性名, 即把表达式放在方括号内, 如:
- let propKey = 'foo';
- let obj = {
- };
表达式还可以用于定义方法名, 如:
- let obj = {
- ['h' + 'ello']() {
- return 'hi';
- }
- };
- obj.hello() // hi
- Object.is()
Object.is()方法判断两个值是否是相同的值. 如果下列任何一项成立, 则两个值相同:
两个值都是 undefined
两个值都是 null
两个值都是 true 或者都是 false
两个值是由相同个数的字符按照相同的顺序组成的字符串
两个值指向同一个对象
两个值都是数字并且
都是正零 +0
都是负零 -0
都是 NaN
都是除零和 NaN 外的其它同一个数字
这种相等性判断逻辑和传统的 == 运算符所用的不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同), 然后才进行相等性比较,(所以才会有类似 "" == false 为 true 的现象), 但 Object.is 不会做这种类型转换.
这与 === 运算符也不一样.=== 运算符 (和 == 运算符) 将数字值 - 0 和 + 0 视为相等, 并认为 Number.NaN 不等于 NaN. 如:
- Object.is('foo', 'foo'); // true
- Object.is(Windows, Windows); // true
- Object.is('foo', 'bar'); // false
- Object.is([], []); // false
- var test = {
- a: 1
- };
- Object.is(test, test); // true
- Object.is(null, null); // true
- // 特例
- Object.is(0, -0); // false
- Object.is(-0, -0); // true
- Object.is(NaN, 0/0); // true
- Object.assign()
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象. 它将返回目标对象.
- const object1 = {
- a: 1,
- b: 2,
- c: 3
- };
- const object2 = Object.assign({
- c: 4, d: 5
- }, object1);
- console.log(object2.a, object2.d);//1 5
Object.assign 拷贝的属性是有限制的, 只拷贝源对象的自身属性(不拷贝继承属性), 也不拷贝不可枚举的属性(enumerable: false). 如:
- Object.assign({
- b: 'c'
- },
- Object.defineProperty({
- }, 'invisible', {
- enumerable: false,
- value: 'hello'
- })
- )
- // {
- b: 'c'
- }
Object.assign 方法实行的是浅拷贝, 而不是深拷贝. 也就是说, 如果源对象某个属性的值是对象, 那么目标对象拷贝得到的是这个对象的引用. 如:
- const obj1 = {
- a: {
- b: 1
- }
- };
- const obj2 = Object.assign({
- }, obj1);
- obj1.a.b = 2;
- obj2.a.b // 2
- Object.values()
Object.values()方法返回一个给定对象自身的所有可枚举属性值的数组, 值的顺序与使用 for...in 循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 ). 如:
- var obj = {
- foo: 'bar', baz: 42
- };
- console.log(Object.values(obj)); // ['bar', 42]
- var obj = {
- 0: 'a', 1: 'b', 2: 'c'
- };
- console.log(Object.values(obj));// ['a', 'b', 'c']
- var an_obj = {
- 100: 'a', 2: 'b', 7: 'c'
- };
- console.log(Object.values(an_obj)); // ['b', 'c', 'a']
- var my_obj = Object.create({
- }, {
- getFoo: {
- value: function() {
- return this.foo;
- }
- }
- });
- my_obj.foo = 'bar';
- console.log(Object.values(my_obj));// ['bar']
- console.log(Object.values('foo'));// ['f', 'o', 'o']
对象的扩展运算符
- let ob = {
- 'a': 1, 'b': 2
- },
- obs = {
- ...ob
- };
- console.log(obs); //{
- 'a': 1, 'b': 2
- }
如果想完整克隆一个对象, 还拷贝对象原型的属性, 可以采用下面的写法. 如:
- // 写法一
- const clone1 = {
- proto: Object.getPrototypeOf(obj),
- ...obj
- };
- // 写法二
- const clone2 = Object.assign(
- Object.create(Object.getPrototypeOf(obj)),
- obj
- );
- // 写法三
- const clone3 = Object.create(
- Object.getPrototypeOf(obj),
- Object.getOwnPropertyDescriptors(obj)
- )
解构赋值
对象的解构赋值用于从一个对象取值, 相当于将目标对象自身的所有可遍历的(enumerable), 但尚未被读取的属性, 分配到指定的对象上面. 所有的键和它们的值, 都会拷贝到新对象上面.
- let {
- x, y, ...z
- } = {
- x: 1, y: 2, a: 3, b: 4
- };
- x // 1
- y // 2
- z // {
- a: 3, b: 4
- }
解构赋值的一个用处, 是扩展某个函数的参数, 引入其他操作. 如:
- function baseFunction({
- a, b
- }) {
- // ...
- }
- function wrapperFunction({
- x, y, ...restConfig
- }) {
- // 使用 x 和 y 参数进行操作
- // 其余参数传给原始函数
- return baseFunction(restConfig);
- }
- (继续完善....)
来源: http://www.qdfuns.com/article/16817/fc1b14babb7e295939f2234ccce709df.html