温故知新之ES6(一)

写了个寂寞 2018-09-12 13:10:50 ⋅ 551 阅读

温故而知新

最近打算看一些 ES TS 计算机 相关的书籍、翻译一些日常搜集的优秀文章、分享一些工作心得,做一些笔记让自己查漏补缺,也分享给大家。

首先感谢阮一峰老师的《ES6标准入门》,写的博客、书、文章很精彩也很易懂。

1. 基本概念

1.1 是什么❓

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了.

1.2 目标是❓

使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

1.3 ECMAScript 和 JavaScript 的关系

ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)。 日常场合,这两个词是可以互换的。

1.4 ES6 与 ECMAScript 2015 的关系

 
  1.   ES6 既是一个历史名词,也是一个泛指,含义是5.1版以后的 JavaScript 的下一代标准,涵盖了ES2015ES2016ES2017等等

  2.   ES2015 则是正式名称,特指该年发布的正式版本的语言标准。

2 let 与 const 区别

let

 
  1.       1. let声明的变量拥有块级作用域

  2.       2. let声明的全局变量不是全局对象的属性

  3.       3. 形如for (let x...)的循环在每次迭代时都为x创建新的绑定。

  4.       4. 不可以重定义

const: 声明一个只读的常量;

本质

 
  1. ·   1. 指向内存地址的变量不能变

  2. ·   2. 基本数据类型【数值、字符串、布尔】不可以变

  3. ·   3. 复合类型的数据【数组、对象】,内容可加,只是指针不可改

声明变量的六种方法

 
  1. ·   var

  2. ·   function

  3. ·   let

  4. ·   const

  5. ·   import

  6. ·   class

  7.  

3. 解构

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

1. 按照对应位置,对变量赋值。

 
  1. // 1

  2. let [a, b, c] = [1, 2, 3];

  3. // 2

  4. let [head, ...tail] = [1, 2, 3, 4];

  5. head // 1

  6. tail // [2, 3, 4]

  7. // 3

  8. let [x, y, ...z] = ['a'];

  9. x // "a"

  10. y // undefined 解构不成功,变量的值就等于 undefined 。

  11. z // []

  12. // 4

  13. let [x, y, z] = new Set(['a', 'b', 'c']);

  14. x // "a"

  15. // 5

  16. let [x, y] = [y, x];

2. 默认值

2.1 解构赋值允许指定默认值。

ES6 内部使用严格相等运算符( === ),判断一个位置是否有值。所以,如果一个数组成员不严格等于 undefined ,默认值是不会生效的。

 
  1. // 1

  2. let [x, y = 'b'] = ['a'];

  3. // x='a', y='b'

  4. // 2 【严格判断】

  5. let [x = 1] = [undefined];

  6. x // 1

  7. // 3 【严格模式】null 不严格等于 undefined 。

  8. let [x = 1] = [null];

  9. x // null

2.2 对象的解构赋值
 
  1. // 1 字段名与变量名不一致的写法,其实就是更名;

  2. //    真正赋值的是后者,

  3. var { foo: baz } = { foo: 'aaa', bar: 'bbb' };

  4. baz // "aaa"

  5. foo // error: foo is not defined

  6. // 2 完整的对象解构的写法

  7. let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

  8. // 简写

  9. let { foo, bar } = { foo: "aaa", bar: "bbb" };

  10. // 3 与数组一样,解构也可以用于嵌套结构的对象。

  11. let obj = {

  12.  p: [

  13.    'Hello',

  14.    { y: 'World' }

  15.  ]

  16. };

  17. let { p: [x, { y }] } = obj;

  18. x // "Hello"

  19. y // "World"

2.3 字符串的解构赋值
 
  1. // 1

  2. let {length : len} = 'hello';

  3. len // 5

  4. // 2

  5. const [a, b, c, d, e] = 'hello';

  6. a // "h"

  7. b // "e"

2.4 函数解构
 
  1. // 1

  2. function move({x = 0, y = 0} = {}) {

  3.  return [x, y];

  4. }

  5. move({x: 3, y: 8}); // [3, 8]

  6. move({x: 3}); // [3, 0]

  7. move({}); // [0, 0]

  8. move(); // [0, 0]

  9. // 2 为函数 move 的参数指定默认值,而不是为变量 x 和 y 指定默认值,所以会得到与前一种写法不同的结果。

  10. function move({x, y} = { x: 0, y: 0 }) {

  11.  return [x, y];

  12. }

  13. move({x: 3, y: 8}); // [3, 8]

  14. move({x: 3}); // [3, undefined]

  15. move({}); // [undefined, undefined]

  16. move(); // [0, 0]

  17. // map 解构

  18. var map = new Map();

  19. map.set('first', 'hello');

  20. map.set('second', 'world');

  21. for (let [key, value] of map) {

  22.  console.log(key + " is " + value);

  23. }

3 用途

 
  1. 1. 交换变量的值; [x, y] = [y, x]

  2. 2. 从函数返回多个值;

  3. 3. 函数参数的定义;

  4. 4. 提取JSON数据;

  5. 5. 函数参数的默认值;

  6. 6. 遍历Map结构;

  7. 7. 输入模块的指定方法

4. 字符串

JavaScript 共有6种方法可以表示一个字符。

 
  1. '\z' === 'z'  // true

  2. '\172' === 'z' // true

  3. '\x7A' === 'z' // true

  4. '\u007A' === 'z' // true

  5. '\u{7A}' === 'z' // true

1 codePointAt

ES6提供了 codePointAt 方法,能够正确处理4个字节储存的字符,返回一个字符的码点。对应老的charAt()

 
  1. var s = '𠮷a';

  2. s.codePointAt(0) // 134071

  3. s.codePointAt(1) // 57271

  4. s.codePointAt(2) // 97

2. String.fromCodePoint()

ES5提供String.fromCharCode 方法,用于从码点返回对应字符,但是这个方法不能识别32位的UTF-16字符(Unicode编号大于 0xFFFF )。

 
  1. String.fromCodePoint(0x20BB7)

  2. // "𠮷"

  3. String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'

  4. // true

上面代码中,如果 String.fromCodePoint 方法有多个参数,则它们会被合并成一个字符串返回。 注意, fromCodePoint 方法定义在 String 对象上,而 codePointAt 方法定义在字符串的实例对象上。

3. at()

 
  1. // ES5

  2. 'abc'.charAt(0) // "a"

  3. // ES6

  4. 'abc'.at(0) // "a"

4. normalize()

ES6 提供字符串实例的 normalize() 方法,用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。

 
  1. '\u01D1'==='\u004F\u030C' //false

  2. '\u01D1'.length // 1

  3. '\u004F\u030C'.length // 2

  4. '\u01D1'.normalize() === '\u004F\u030C'.normalize()

  5. // true

5. 其余汇总

 
  1. 1. includes():返回布尔值,表示是否找到了参数字符串。

  2. 2. startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。

  3. 3. endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。

  4. 4. repeat(): 表示将原字符串重复 n 次。

  5. 5. padStart(): 某个字符串不够指定长度 头部补全

  6. 6. padEnd(): 某个字符串不够指定长度 尾部补全

 
  1. var s = 'Hello world!';

  2. s.startsWith('Hello') // true

  3. s.endsWith('!') // true

  4. s.includes('o') // true

  5. 'x'.repeat(3) // "xxx"

  6. 'na'.repeat(0) // ""

  7. // 参数 NaN 等同于0。

  8. 'na'.repeat(NaN) // ""

  9. 'x'.padStart(5, 'ab') // 'ababx'

  10. 'x'.padStart(4, 'ab') // 'abax'

  11. 'x'.padEnd(5, 'ab') // 'xabab'

  12. 'x'.padEnd(4, 'ab') // 'xaba'

5. 数值扩展

1. 二进制和八进制表示法

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b (或 0B )和 0o (或 0O )表示。

 
  1. 0b111110111 === 503 // true

  2. 0o767 === 503 // true

2. Number 新加方法

 
  1. 1. Number.isFinite():  Number.isFinite() 用来检查一个数值是否为有限的(finite)。

  2. 2. Number.isNaN():  Number.isNaN() 用来检查一个值是否为 NaN

  3. 3. Number.parseInt(): 格式化为int

  4. 4. Number.parseFloat(): 格式化为float

  5. 5. Number.isInteger() 判断是否是整数

  6. 6. 安全整数和Number.isSafeInteger()

  7.    JavaScript能够准确表示的整数范围在 -2^53 2^53 之间(不含两个端点),超过这个范围,无法精确表示这个值。

  8.     Number.isSafeInteger() 则是用来判断一个整数是否落在这个范围之内。

  9. 7. Number.EPSILON: 新增极小的常量,float是不准确的,

  10.    计算时与该值比较,如果小于,即可,

  11.    Number.EPSILON// 2.220446049250313e-16

  12.    Number.EPSILON.toFixed(20)

  13.    // '0.00000000000000022204'===

  14.    function withinErrorMargin (left, right) {

  15.      return Math.abs(left - right) < Number.EPSILON;

  16.    }

  17.    withinErrorMargin(0.1 + 0.2, 0.3)

  18.    // true

3. Math对象的扩展

新增方法

 
  1. 1. Math.trunc(): 去除一个数的小数部分,返回整数部分;

  2. 2. Math.sign(): 判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。

  3.    参数为正数,返回+1

  4.    参数为负数,返回-1

  5.    参数为0,返回0

  6.    参数为-0,返回-0;

  7.    其他值,返回NaN

  8. 3. Math.cbrt() 方法用于计算一个数的立方根。

  9. 4. Math.clz32() 方法返回一个数的32位无符号整数形式有多少个前导0

  10. 5.  Math.imul 方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数。

  11. 6. Math.fround方法返回一个数的单精度浮点数形式。

  12. 7.  Math.hypot 方法返回所有参数的平方和的平方根。

  13. 8. Math.expm1(x) 返回ex - 1,即 Math.exp(x) - 1

  14. 9. Math.expm1(x) 返回ex - 1,即 Math.exp(x) - 1

  15. 10.  Math.log10(x) 返回以10为底的 x 的对数。如果 x 小于0,则返回NaN

  16. 11.  Math.log2(x) 返回以2为底的 x 的对数。如果 x 小于0,则返回NaN

  17. 12. ES2016 新增了一个指数运算符( ** )。

  18.    2 ** 2 // 4

  19.    2 ** 3 // 8

  20.    let a = 1.5;

  21.    a **= 2;

  22.    // 等同于 a = a * a;

  23.    a **= 3 // a = a * a * a

6. 函数的扩展

1. 函数参数的默认值【结合解构】

参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

 
  1. let x = 99;

  2. function foo(p = x + 1) {

  3.  console.log(p);

  4. }

  5. foo() // 100

  6. x = 100;

  7. foo() // 101

2. 应用

 
  1. function throwIfMissing() {

  2.  throw new Error('Missing parameter');

  3. }

  4. function foo(mustBeProvided = throwIfMissing()){

  5.  return mustBeProvided;

  6. }

  7. foo()

  8. // Error: Missing parameter

3. rest 参数

ES6 引入 rest 参数(形式为 ...变量名 ),用于获取函数的多余参数,这样就不需要使用 arguments

ES6 引入 rest 参数(形式为 ...变量名 ),用于获取函数的多余参数,这样就不需要使用 arguments

4. name 属性

函数的 name 属性,返回该函数的函数名。

 
  1. function foo() {}

  2. foo.name // "foo"

5. 箭头函数

 
  1. // 正常函数写法

  2. [1,2,3].map(function (x) {

  3.  return x * x;

  4. });

  5. // 箭头函数写法

  6. [1,2,3].map(x => x * x);

箭头函数有几个使用注意点。

 
  1. 1)函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。

  2. 2)不可以当作构造函数,也就是说,不可以使用 new 命令,否则会抛出一个错误。

  3. 3)不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

  4. 4)不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。

 
  1. function foo() {

  2. // 箭头函数导致 this 总是指向函数定义生效时所在的对象(本例是 {id: 42} ),所以输出的是 42 。

  3.  setTimeout(() => {

  4.    console.log('id:', this.id);

  5.  }, 100);

  6. }

  7. var id = 21;

  8. foo.call({ id: 42 });

  9. // id: 42

下面函数有几个this ??

 
  1. function foo() {

  2.  return () => {

  3.    return () => {

  4.      return () => {

  5.        console.log('id:', this.id);

  6.      };

  7.    };

  8.  };

  9. }

  10. var f = foo.call({id: 1});

  11. var t1 = f.call({id: 2})()(); // id: 1

  12. var t2 = f().call({id: 3})(); // id: 1

  13. var t3 = f()().call({id: 4}); // id: 1

上面代码之中,只有一个 this ,就是函数 foo 的 this ,所以 t1 、 t2 、 t3 都输出同样的结果。因为所有的内层函数都是箭头函数,都没有自己的 this ,它们的 this 其实都是最外层 foo 函数的 this 。

除了 this ,以下三个变量在箭头函数之中也是不存在的,指向外层函数的对应变量: arguments 、 super 、 new.target 。

7. 绑定 this

箭头函数可以绑定 this 对象,大大减少了显式绑定 this 对象的写法( call 、 apply 、 bind )。但是,箭头函数并不适用于所有场合,所以ES7提出了“函数绑定”(function bind)运算符,用来取代 call 、 apply 、 bind 调用。虽然该语法还是ES7的一个提案,但是Babel转码器已经支持。

函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。

 
  1. foo::bar;

  2. // 等同于

  3. bar.bind(foo);

  4. foo::bar(...arguments);

  5. // 等同于

  6. bar.apply(foo, arguments);

  7. const hasOwnProperty = Object.prototype.hasOwnProperty;

  8. function hasOwn(obj, key) {

  9.  return obj::hasOwnProperty(key);

  10. }



---------------END----------------

后续的内容同样精彩

长按关注“IT实战联盟”哦



全部评论: 0

    我有话说:

    温故知新ES6(二)

    温故知新ES6 基础类型

    温故知新ES6(三)

    温故知新ES6 数组集合和字典

    温故知新ES6(二)

    紧接本系列上篇

    玩转ES6(三):数据结构

    Set 是ES6提供的种新的数据结构,它允许你存储任何类型的唯一值,而且Set中的元素是唯一的。

    玩转ES6(五):Iterator、Generator、async/await

    1. Iterator 和 for…of 循环 ES6 中有四种数据集合:数组( Array )、对象( Object )、Map 和 Set 。这样就需要种统一的接口机制,来处理所有不同的数据

    「开源资讯」Gradle 6.7 发布,增量构建改进

    Gradle 6.7 已经发布。Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的项目自动化构建工具,支持依赖管理和多项目,类似 Maven,但比简单轻便。它使用

    Node模块Events模块(五)

    Node模块Events模块(五)

    Debian 10.6 发布

    Debian 10.6 已发布,这是 Debian 10 "Buster" 的第六个稳定版更新,修复了部分安全问题和 bug。 除了安全方面的更新,还有针对 OpenJDK, Firefox ESR

    Express 系列---概述()

    Express是目前最流行的基于Node.js的Web开发框架,可以快速地搭建一个完整功能的网站。

    MongoDB系列----概述()

    MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。

    Java Web实战篇-代码

    代码美-小小的优化让你的代码Bug更少,执行效率更高

    京东到家订单中心系统mysql到es的转化

    原文:https://www.toutiao.com/i6796507988602389006 京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调用量都非常大,造成了订单数据读多写少的情况。 我们把订单数...

    Linux 下安装 Elasticsearch5.6.x 详细步骤以及踩坑解决方案

    网上有各种ES版本的安装步骤和问题解决方案,但是在安装过程中还是遇到了许多问题,那么今天来整理份详细的安装过程以及碰到的问题和心得;有什么不对的和问题希望大家留言一起讨论。

    Python 3.8.6 发布

    Python 3.8.6 发布了,它是 Python 3.8 的第六个维护版本。 3.8 系列的维护版本将每两个月定期更新次,3.8.7 计划于 2020 年 11 月中旬发布。 随着维护版本的

    VirtualBox 6.1.18 发布,开源虚拟机

    VirtualBox 6.1.18 现已发布。VirtualBox 是款功能强大的 x86 虚拟机软件,它不仅具有丰富的特色,而且性能也很优异。 该版本是一个维护版本,修复和/或添加了以下项目

    OpenSSH 8.6 发布

    OpenSSH 8.6 已发布,OpenSSH 是 100% 完整的 SSH 协议 2.0 版本的实现,并且包括 sftp 客户端和服务器支持,它用于远程登录的主要连接工具。OpenSSH

    代码整洁道:Lombok 的使用

    Lombok项目是种自动接通你的编辑器和构建工具的一个Java库。不用再次写额外的getter或者equals方法。

    Redis 6.2.2 发布

    Redis 6.2.2 现已发布,该版本升级迫切性程度为高。对于那些使用 ACL 和 pub/sub,CONFIG REWRITE,或遭受性能下降影响的用户来说,详见下文: 修复了