ECMAScript 6 常用特性整理
来源:互联网 发布:pycharm和python 编辑:程序博客网 时间:2024/06/05 18:05
ECMAScript 6 常用特性整理
说明
看了 阮一峰 老师的 ECMAScript 6 入门,决定将之前一直使用到的 ES6 重新整理一遍。
1. let 和 const
用法类似
var
用来声明变量,但是声明的变量只在命令所在的代码块中有效不存在变量提升
暂时性死区, 在变量用 let 声明前的代码中 只要使用到变量,就会报错
不允许重复声明变量
const 声明的是一个只读的常量,声明后值不可以改变
对于对象和数组来说,变量指向内存地址,保存的只是一个指针,const 声明的变量可以保证指针不变,但是指向的数据结构发生变化就是不可控的
2. 块级作用域
let 和 const 声明的变量存在块级作用于, ES6 允许块级作用域的任意嵌套,外层的作用域无法读取内层作用域的变量
应该避免在块级作用域内声明函数,如果需要声明函数,要使用函数表达式
3. 变量的解构赋值
解构赋值等号的右边需要时可遍历结构
1. 数组的解构赋值
let [a, [b], d] = [1, [2, 3], 4]; console.log(a, b, d); // 1, 2, 4 // 等号右边需要时可遍历结构 let [f] = 121212; console.log(f); // 报错 // 指定默认值 let [foo = true] = []; console.log(foo); // true // ES6 内部使用严格相等 === 判断一个位置是否有值,=== undefined 才会使用默认值 let [x = 1] = [undefined]; let [y = 1] = [null]; console.log(x, y); // 1 null // 惰性求值 function f () { // 未执行,只有 x 取不到值的时候才会执行 console.log('aaa'); } let [x = f()] = [1]; console.log(x); // 1 // 默认值引用解构赋值的其他变量 let [x = 1, y = x] = []; console.log(x, y); // 1 1 let [x, y = x] = [1]; console.log(x, y); // 1 1 let [x = y, y = 1] = []; console.log(x, y); // 报错
2. 对象的解构赋值
let {a: aa} = {a: 1, b: 2}; // 想找到同名的属性 'a' 然后复制给变量 'aa' console.log(aa); // 1 // 变量的解构赋值是变量声明和赋值一体的,所以要赋值的变量不能提前声明 let a = 12; let [a] = [1, 2, 3]; console.log(a); // 报错 let a = 12; let b; [a] = [1, 2, 3]; ({b} = {b: 1}); // 需要放在'()'里 否则会把 {b} 解析为代码块 console.log(a, b); // 成功 1 1 // 数组是特殊的对象 let {0: fir, 1: sec} = [1, 2, 3]; console.log(fir, sec); // 1 2
3. 字符串的解构赋值
// 字符串会被转换成类数组对象,含有 length 属性 let [a, b] = 'hello'; console.log(a, b); // h e let {length: len} = 'hello'; console.log(len); // 5
4. 函数参数的解构赋值
function f([a,b]) { return a + b; } console.log(f([1, 2])); // 3 // 使用默认值 function f ({x = 'x', y = 'y'} = {}) { console.log([x, y]); } f(); // ["x", "y"] 不传入参数 参数按照默认值解构 {x = 'x', y = 'y'} = {} ({},是参数中的) f({}); // ["x", "y"] 传入参数 参数按照传入的值解构 {x = 'x', y = 'y'} = {} ({}, 是传入的 {}) f({x: 1}); // [1, "y"] 传入参数 参数按照传入的值解构 {x = 'x', y = 'y'} = {x: 1} // 另外一种默认值的写法 function f ({x, y} = {x: 'x', y: 'y'}) { console.log([x, y]); } f(); // ["x", "y"] 不传入参数 参数按照默认值解构 {x, y} = {x: 'x', y: 'y'} f({}); // [undefined, undefined] 传入参数 参数按照传入的值解构 {x, y} = {} f({x: 1}); // [1, undefined] 传入参数 参数按照传入的值解构 {x, y} = {x: 1}
4. 字符串扩展
模板字符串
// 一般写法 `hello hello` // 多行 ` hello hello hello ` // 变量 `hello ${name} hello`
更多字符串方法 javascript字符串方法汇总
5. 数值的扩展
1. Number.isFinite() 是否为有限的
Number.isFinite(1); // true Number.isFinite(NaN); // false Number.isFinite(Infinity); // false Number.isFinite(true); // false
2. Number.isNaN() 是否为 NaN
Number.isNaN(NaN); // true Number.isNaN(15); // false
3. Number.parseInt(), Number.parseFloat() 移植到 Number 上了
4. Number.isInteger() 判断值是否为整数
Number.isInteger(3.3); // false Number.isInteger(3.0); // true
5. Math.trunc() 除去数字的小数部分,返回整数部分 (内部使用 Number 方法装换为数值)
Math.trunc(123.22); // 123 Math.trunc('123.22'); // 123 Math.trunc(true); // 1 Math.trunc(null); 0 Math.trunc(undefined); // NaN Math.trunc({}); // NaN Math.trunc([]); // 0 Math.trunc('a123'); // NaN
6. 数组的扩展
1. Array.from() 将类数组对象转换为真正的数组
let obj = { '0': 'a', '1': 'b', '2': 'c', length: 3 } const arr = Array.from(obj); console.log(arr); // ["a", "b", "c"] function f () { const args = Array.from(arguments, (x) => x + '--add'); console.log(args); } f('a', 'c'); //["a--add", "c--add"]
2. Array.of() 将一组数值转化为数组
const arr = Array.of(12,12,12); console.log(arr); // [12, 12, 12]
3. find() findIndex() 找到第一个符合条件的数组成员,参数是一个回调函数,数组成员依次执行回调,直到第一个返回值为true的成员,然后返回此成员或者所在index,没有则返回undefined
const member = [22, 323, 424, -12, 0].find((value, index) => { return value < 0; }) console.log(member); // -12 const member = [22, 323, 424, -12, 0].findIndex((value, index) => { return value < 0; }) console.log(member); // 3
更多数组方法,在 Javascript 数组方法汇总 中
7. 函数的扩展
ES6 中的函数参数可以设置默认值,函数进行声明初始化的时候,参数会形成一个单独的作用域,初始化结束后这个作用域就会消失,这种行为在不设置参数默认值时是不存在的
// 参数中 y 默认等于 x 变量,调用函数是,参数新城单独作用域,y 指向参数 x 而不是全局的 x var x = 1; function f(x, y = x) { console.log(y); } f(2) // 2 // foo 在 bar 函数的参数作用域中没有定义,所以指向全局的 foo let foo = 'outer'; function bar(func = x => foo) { let foo = 'inner'; console.log(func()); } bar(); // outer
1. rest 参数, 有点类似逆向的扩展运算符
function f (...args) { console.log(args); // [1, 2, Array(2), function] } f(1, 2, [11, 22], function () { console.log('in'); });
2. 扩展运算符, 将一个数组转为用逗号分隔的参数序列。
// 函数使用 function f (a, b) { console.log(a, b); } const arr = [123, 456]; f(...arr); // 123 456 // 合并数组 const arr1 = ['a', 'b', 'c']; const arr2 = [1, 2, 3]; const arr = [...arr1, ...arr2]; console.log(arr); // ["a", "b", "c", 1, 2, 3] // 结合解构赋值 const arr1 = ['a', 'b', 'c']; const [fir, ...sec] = arr1; console.log(fir, sec); // a ["b", "c"] // 结构赋值时,要放在最后,否则报错 const arr1 = ['a', 'b', 'c']; const [...fir, sec] = arr1; console.log(fir, sec); // 报错 // 可以用来将字符串转换成数组 const arr = [...'hello']; console.log(arr); // ["h", "e", "l", "l", "o"]
3. 严格模式
ES6 中的 严格模式可以设置成全局的,但是在函数中的严格模式需要函数参数不包含 默认值、解构赋值、扩展运算符,否则会报错
4. 箭头函数, 简化回调函数
- 函数体内的 this 对象 就是定义时所在的对象,不是使用时的对象
- 不可以当做构造函数,也就是不也已使用 new 命令
- 不可以使用 arguments 对象,不存在,可以用 rest 参数 代替
- 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数
// 定义函数, 一个参数 let f = x => x; // 没有参数 用 () let f = () => 'test'; // 多个参数 (x, y) let f = (a, b) => a + b; // 代码块多于一行 let f = (a, b) => { let num = a + b; return num; }
8. 对象的扩展
// 对象的一般写法 let foo = 'foo'; let obj = {foo: foo}; // 简洁的写法 let obj = {foo}; // 属性名 = 变量名 // 方法的简写 const obj = { method(){ console.log('method'); } }
1. ES6 允许表达式作为对象的属性名或者方法名
// 属性名 let prop = 'foo'; let obj = { [prop]: true, ['a' + 'b']: 123 }; console.log(obj); // {foo: true, ab: 123} // 方法名 let prop = 'foo'; let obj = { [prop]() { console.log('obj.foo function'); } } obj.foo(); // obj.foo function // 属性名表达式与简洁表示法不能同时用,会报错 let foo = 'bar'; let bar = 'abc'; let obj = { [foo] // 报错 }
2. Object.is() 比较两个值是否相等,基本与 === 差不多
// 与 === 不一样的地方 NaN === NaN // false -0 === +0 // true Object.is(-0, +0) // false Object.is(NaN, NaN) // true
3. Object.assign() 实现浅拷贝,用于合并对象,将源对象的所有可枚举属性,复制到目标对象
// 第一个参数是目标对象,后面的参数是源对象,有同名的属性,后边的会覆盖前边的 let target = {a: 1, b: 2}; let source1 = {b: 4, c: 8}; let source2 = {c: 6}; const a = Object.assign(target, source1, source2); console.log(a); // {a: 1, b: 4, c: 6} console.log(target); // {a: 1, b: 4, c: 6} // 指定默认值 const defaultVal = { level: 1, type: 'html' } function f (options) { options = Object.assign({}, defaultVal, options); return options; } console .log(f({level: 2})); // {level: 2, type: "html"}
4. 对象的扩展运算符
// 解构赋值, ... 必须在最后,并且 = 右边需要是一个对象 let {x, y, ...d} = {x: 'x', p: 'p', y: 'y', c: 'c'}; console.log(d); // {p: "p", c: "c"} // 作为扩展,可以有多个 ... let a = {x: '1212', y: '1222'}; let b = {z: 'zzz', y: '12ed'}; let ab = {...a, ...b}; console.log(ab); // {x: "1212", y: "12ed", z: "zzz"}
9. Set
- Set 数据结构类似数组,但是成员的值都是唯一的,没有重复的值,可以用来数组去重
// 初始化 const set = new Set([1, 2, 1, 3 ,2 , 5]); console.log([...set]); // [1, 2, 3, 5] // 添加 set.add(123); set.add(2); console.log([...set]); // [1, 2, 3, 5] // 数组去重, 向Set 中加入值的时候不会发生类型转换 let arr = [1, 2, 1, 3 ,2 , 5, '5']; const output = [...new Set(arr)]; console.log(output); // [1, 2, 3, 5, "5"] // NaN 与 NaN 比较算是重复的 let arr = [1, NaN]; let set = new Set(arr); console.log(set.size); // 2 set.add(NaN); const output = [...set]; console.log(output); // [1, NaN]
- set 实例的方法
let set = new Set([1, 2, 3, 2, 5]); console.log(set.size); // 4 返回 Set 实例的成员总数 set.add(8); // SetIterator {1, 2, 3, 5, 8} 添加值 set.delete(5); // SetIterator {1, 2, 3, 8} 删除值 set.has(8); // true 是否含有某个值 set.clear(); // [] 清除所有值,没有返回值 for (let item of set.keys()) { console.log(item); // 1 2 3 5 返回键名,Set 没有键名就返回键值,跟 set.values一样 } for (let item of set.values()) { console.log(item); // 1 2 3 5 返回键值 } for (let item of set.entries()) { console.log(item); // [1, 1] [2, 2] [3, 3] [5, 5] 返回键值对 } set.forEach((item, i) => { console.log(item, i); // 遍历 });
- set 实现并集、交集、差集
let a = new Set([1, 2, 3]); let b = new Set([4, 2, 3]); // 并集 const union = new Set([...a, ...b]); console.log(union); // Set(4) {1, 2, 3, 4} // 交集 const intersect = new Set([...a].filter(x => b.has(x))); console.log(intersect); // Set(2) {2, 3} // 差集 const diff = new Set([...a].filter(x => !b.has(x))); console.log(diff); // Set(1) {1}
10. Map
Object 对象是键值对的集合,但是传统上只能用 字符串做键,而 Map 结构上类似 Object 也是键值对的集合,但是键的范围不限制于字符串,各种类型的值都可以作为键,如果键的值是引用类型则,键实际上是指针指向的地址
const a = new Map(); const o1 = {name: 'xiaoming'}; const o2 = {name: 'xiaoming'}; // set 方法用于设置键值对 a.set(o1, 'this is xiaoming'); // has 方法用于判断是否含有值 console.log(a.has(o1)); // true // o1 和 o2 是值相同但是指向不同内存地址的对象 console.log(a.get(o1)); // this is xiaoming console.log(a.get(o2)); // undefined // o1 作为键内存地址不改变但是值变了,Map 依然可以通过 get 方法取到值,证明 键实际上是指针的指向地址 o1.age = 23; // get 方法用于获取值 console.log(a.get(o1)); // this is xiaoming 不变 // delete 方法用作删除 a.delete(o1); console.log(a.has(o1)); // false // 设置多个键值对 const b = new Map([ ['name', 'xiaoming'], ['age', 90] ]) console.log(b.has('name')); // true console.log(b.has('age')); // true // size 属性 返回 map 成员总数 console.log(b.size); // 2 // clear 方法清除所有成员 b.clear(); console.log(b.has('name')); // false const b = new Map([ [{name: 'firstName'}, 'xiaoming'], ['age', 90] ]) // 返回键名 for (let key of b.keys()) { console.log(key); // {name: "firstName"} age } // 返回键值 for (let value of b.values()) { console.log(value); // xiaoming 90 } // 返回所有成员 for (let item of b.entries()) { console.log(item); // [{name: "firstName"}, "xiaoming"] ["age", 90] } // 遍历所有成员 b.forEach(function (value, key, map) { console.log(value, key); // xiaoming {name: "firstName"} // 90 "age" })
11. Class
javascript 中,生成实例对象的传统方法是通过构造函数,es6 引入 Class 作为对象的模板,通过 Class 定义类,但是 es6 的 Class 只是一个语法糖,他只是在写法上更像面向对象编程的语法而已,es6 的类可以看做是构造函数的另外一种写法
class Parent { /* 通过 new 生成实例对象时,自动调用该方法, 一个类必须有此方法,如果没有显示定义,空的constructor会被自动添加 constructor 方法默认返回实例对象 即 this */ constructor(x, y) { /* 这里的 this 指向实例化后的对象, */ this.attrs = { a: 'a' }; } // 定义实例属性 constructor 中也可以通过 this 定义 state = { name: 'state name' }; /* 方法之间不能有逗号, 定义的方法都挂载在 Parent.prototype 上了 类的方法中如果有 this 默认指向类的实例,但是如果将方法提取出来单独使用,this 会指向该方法所在的运行环境, 这个时候如果想通过 this 调用 类中定义的方法或属性就会找不到,解决办法是手动绑定 `.bind(this)` */ show() { } // 静态属性 由类直接调用 static classAttr = 'class attr'; // 静态方法 由类直接调用 static classMethod() { console.log('static'); } } /* 类 必须要通过 new 调用否则会报错(普通构造函数可以直接使用) 不存在变量提升,子类一定要在父类后定义 */ Parent.classMethod(); // static console.log(Parent.classAttr); // class attr const parent = new Parent(); console.log(Parent.name); // Parent console.log(parent.state); // {name: "state name"} console.log(parent.attrs); // {a: "a"} console.log(parent.__proto__ === Parent.prototype); // true console.log(parent.__proto__.constructor === Parent); // true console.log(Parent.prototype); // {constructor: function, show: function} /* Class 表达式方式定义 me 只用作函数内使用, 不使用的话可以省略 函数外类叫做 MyClass */ const MyClass = class me { getClassName() { return me.name } } const a = new MyClass(); console.log(a.getClassName()); // me
类的继承,(extends)
- es5 的继承,实质上是先创建子类的实例对象 this ,然后将父类的方法添加到 this 上
- es6 的继承机制完全不同,实质上是先创建父类的实例对象 this (所以必须先调用super方法),然后再用子类的构造函数修改 this,子类中只有调用了 super 方法之后 才可以使用 this 关键字
class Parent { constructor(name) { this.name = name; } logName(newName) { console.log(newName); } } // 子类 通过 extends 关键字继承父类 class Child extends Parent { constructor(age, name) { /* super 表示父类的构造函数(constructor(name)) 子类必须在 constructor 方法中调用 super 否则会因为子类没有自己的 this 对象 又没有通过 super 继承父类的 this 而报错 */ super(name); this.age = age; } logAge() { console.log(this.age) } logName() { console.log('this is in Child'); } logInfo() { // 调用 logName 方法,子类覆盖了父类 this.logName(this.name); // 直接调用父类 的 logName 方法 super.logName(this.name); this.logAge(); } } console.log(Child.prototype.constructor === Child); // true const child = new Child(20, 'xiaobai'); child.logInfo(); // this is in Child | xiaobai | 20
更多文章
- ECMAScript 6 常用特性整理
- Promise-使用整理
- Decorator装饰器
- Iterator、Generator、async、await 异步编程
- ECMAScript 6 常用特性整理
- ECMAScript 6 常用特性整理
- ECMAScript 6 新特性
- ECMAScript 6新特性
- ECMAScript 6新特性介绍
- ECMAScript 6新特性介绍
- ECMAScript 6新特性简记
- ECMAScript 6新特性简记
- ECMAScript 6新特性简记
- ECMAScript 6新特性简记
- ECMAScript 6新特性简记
- ECMAScript 6 十大特性
- ECMAScript 6新特性简记
- ECMAScript 6 十大特性
- ECMAScript 6 的新特性
- ECMAScript 6 中的 String 新特性
- ECMAScript 6新特性之Proxy
- Java常用容器特性整理
- slf4j log4j logback关系详解和相关用法
- java备份数据库四种方法(mysql,mssql数据库备份)
- LeetCode 二分查找第K大的数215. Kth Largest Element in an Array
- linux下编译C++程序
- SIP穿越NAT的rport机制
- ECMAScript 6 常用特性整理
- 记(Laravel)PDO 使用prepared statement 预处理LIMIT等字段遇到的坑。
- 开发者都应该使用的10个C++11特性
- 【字符串】查找一个字符串中第一个只出现两次的字符。比如:“abcdefabcdefabc”中第一个只出现两次为‘d’,要求时间复杂度为O(N),空间复杂度为O(1)
- Angular4+NodeJs+MySQL 入门-02 MySql操作类
- js将 一串数字1403149534转换为日期格式
- (转载)request.getParameter() 和request.getAttribute() 区别
- 快速排序 分治法
- 监听器listener.ora中HOST参数配置