美文网首页
温故知新之ES6(一)

温故知新之ES6(一)

作者: simuty | 来源:发表于2018-09-07 19:15 被阅读36次

温故而知新

最近打算看一些 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 的关系

•   ES6 既是一个历史名词,也是一个泛指,含义是5.1版以后的 JavaScript 的下一代标准,涵盖了ES2015、ES2016、ES2017等等
•   ES2015 则是正式名称,特指该年发布的正式版本的语言标准。

2 let 与 const 区别

let

    •   1. let声明的变量拥有块级作用域
    •   2. let声明的全局变量不是全局对象的属性
    •   3. 形如for (let x...)的循环在每次迭代时都为x创建新的绑定。
    •   4. 不可以重定义

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

本质

·   1. 指向内存地址的变量不能变
·   2. 基本数据类型【数值、字符串、布尔】不可以变
·   3. 复合类型的数据【数组、对象】,内容可加,只是指针不可改

声明变量的六种方法

·   var 
·   function
·   let
·   const
·   import
·   class
•   

3. 解构

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

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

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

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

// 3 
let [x, y, ...z] = ['a'];
x // "a"
y // undefined 解构不成功,变量的值就等于 undefined 。
z // []

// 4
let [x, y, z] = new Set(['a', 'b', 'c']);
x // "a"

// 5 
let [x, y] = [y, x];

2. 默认值

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

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

// 1
let [x, y = 'b'] = ['a']; 
// x='a', y='b'

// 2 【严格判断】
let [x = 1] = [undefined];
x // 1

// 3 【严格模式】null 不严格等于 undefined 。
let [x = 1] = [null];
x // null


2.2 对象的解构赋值
// 1 字段名与变量名不一致的写法,其实就是更名;
//    真正赋值的是后者,
var { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
foo // error: foo is not defined



// 2 完整的对象解构的写法
let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
// 简写
let { foo, bar } = { foo: "aaa", bar: "bbb" };

// 3 与数组一样,解构也可以用于嵌套结构的对象。
let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};
let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"

2.3 字符串的解构赋值
// 1
let {length : len} = 'hello';
len // 5

// 2
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"

2.4 函数解构

// 1
function move({x = 0, y = 0} = {}) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

// 2 为函数 move 的参数指定默认值,而不是为变量 x 和 y 指定默认值,所以会得到与前一种写法不同的结果。
function move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

// map 解构
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}


3 用途

1. 交换变量的值; [x, y] = [y, x]
2. 从函数返回多个值;
3. 函数参数的定义;
4. 提取JSON数据;
5. 函数参数的默认值;
6. 遍历Map结构;
7. 输入模块的指定方法

4. 字符串

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

'\z' === 'z'  // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true

1 codePointAt

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

var s = '𠮷a';
s.codePointAt(0) // 134071
s.codePointAt(1) // 57271
s.codePointAt(2) // 97

2. String.fromCodePoint()

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

String.fromCodePoint(0x20BB7)
// "𠮷"
String.fromCodePoint(0x78, 0x1f680, 0x79) === 'x\uD83D\uDE80y'
// true

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

3. at()

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

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

4. normalize()

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

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


'\u01D1'.normalize() === '\u004F\u030C'.normalize()
// true

5. 其余汇总

1. includes():返回布尔值,表示是否找到了参数字符串。
2. startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
3. endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
4. repeat(): 表示将原字符串重复 n 次。
5. padStart(): 某个字符串不够指定长度 头部补全
6. padEnd(): 某个字符串不够指定长度 尾部补全

var s = 'Hello world!';

s.startsWith('Hello') // true

s.endsWith('!') // true

s.includes('o') // true

'x'.repeat(3) // "xxx"
'na'.repeat(0) // ""
// 参数 NaN 等同于0。
'na'.repeat(NaN) // "" 

'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

5. 数值扩展

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

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

0b111110111 === 503 // true
0o767 === 503 // true

2. Number 新加方法

1. Number.isFinite():  Number.isFinite() 用来检查一个数值是否为有限的(finite)。
2. Number.isNaN():  Number.isNaN() 用来检查一个值是否为 NaN 。
3. Number.parseInt(): 格式化为int
4. Number.parseFloat(): 格式化为float
5. Number.isInteger() 判断是否是整数
6. 安全整数和Number.isSafeInteger()
    JavaScript能够准确表示的整数范围在 -2^53 到 2^53 之间(不含两个端点),超过这个范围,无法精确表示这个值。
     Number.isSafeInteger() 则是用来判断一个整数是否落在这个范围之内。
 
7. Number.EPSILON: 新增极小的常量,float是不准确的,
    计算时与该值比较,如果小于,即可,
    Number.EPSILON// 2.220446049250313e-16
    Number.EPSILON.toFixed(20)
    // '0.00000000000000022204'=== 
    function withinErrorMargin (left, right) {
      return Math.abs(left - right) < Number.EPSILON;
    }
    withinErrorMargin(0.1 + 0.2, 0.3)
    // true

3. Math对象的扩展

新增方法

1. Math.trunc(): 去除一个数的小数部分,返回整数部分;
2. Math.sign(): 判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
    参数为正数,返回+1;
    参数为负数,返回-1;
    参数为0,返回0;
    参数为-0,返回-0;
    其他值,返回NaN

3. Math.cbrt() 方法用于计算一个数的立方根。
4. Math.clz32() 方法返回一个数的32位无符号整数形式有多少个前导0。
5.  Math.imul 方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数。
6. Math.fround方法返回一个数的单精度浮点数形式。
7.  Math.hypot 方法返回所有参数的平方和的平方根。
8. Math.expm1(x) 返回ex - 1,即 Math.exp(x) - 1 。
9. Math.expm1(x) 返回ex - 1,即 Math.exp(x) - 1 。
10.  Math.log10(x) 返回以10为底的 x 的对数。如果 x 小于0,则返回NaN。
11.  Math.log2(x) 返回以2为底的 x 的对数。如果 x 小于0,则返回NaN。
12. ES2016 新增了一个指数运算符( ** )。
    2 ** 2 // 4
    2 ** 3 // 8
    let a = 1.5;
    a **= 2;
    // 等同于 a = a * a;
    a **= 3 // a = a * a * a

6. 函数的扩展

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

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

let x = 99;
function foo(p = x + 1) {
  console.log(p);
}
foo() // 100

x = 100;

foo() // 101

2. 应用

function throwIfMissing() {
  throw new Error('Missing parameter');
}

function foo(mustBeProvided = throwIfMissing()){
  return mustBeProvided;
}

foo()

// Error: Missing parameter

3. rest 参数

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

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

4. name 属性

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

function foo() {}
foo.name // "foo"

5. 箭头函数

// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭头函数写法
[1,2,3].map(x => x * x);

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

(1)函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用 new 命令,否则会抛出一个错误。
(3)不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。
function foo() {
// 箭头函数导致 this 总是指向函数定义生效时所在的对象(本例是 {id: 42} ),所以输出的是 42 。
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;
foo.call({ id: 42 });
// id: 42

下面函数有几个this ??

function foo() {
  return () => {
    return () => {
      return () => {
        console.log('id:', this.id);
      };
    };
  };
}

var f = foo.call({id: 1});
var t1 = f.call({id: 2})()(); // id: 1
var t2 = f().call({id: 3})(); // id: 1
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对象),绑定到右边的函数上面。

foo::bar;
// 等同于
bar.bind(foo);
foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);

const hasOwnProperty = Object.prototype.hasOwnProperty;

function hasOwn(obj, key) {
  return obj::hasOwnProperty(key);
}

相关文章

  • 温故知新之ES6(一)

    温故而知新 最近打算看一些 ES TS 计算机 相关的书籍、翻译一些日常搜集的优秀文章、分享一些工作心得,做一些笔...

  • 温故知新之ES6(四)

    希望大家看到这个字数,不要被吓到,Proxy / Reflect 真的很值得学习的 1.Proxy概述 Proxy...

  • 温故知新之ES6(三)

    1. SET ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身...

  • 温故知新之ES6(二)

    目录 1. 数组的扩展 1 扩展运算符 扩展运算符(spread)是三个点( ... )。它好比 rest 参数的...

  • 温故知新之ES6(五)

    1. Iterator 和 for...of 循环 ES6 中有四种数据集合:数组( Array )、对象( Ob...

  • 温故知新之ES6(七)

    Airbnb 1. 块级作用域 let 取代 var. 全局常量和线程安全 2. 字符串 静态字符串一律使用单引号...

  • 温故知新之ES6(六)

    1. Class 的基本语法 JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。...

  • ES6 温故知新

    let / const ES6 种用来定义变量和常量的 机遇 CONST 创建的变量,变量存储的值不能被修改(常量...

  • ES6——Reflect 与 Proxy

    ES6 之 Proxy 介绍深入实践 ES6 Proxy & Reflect 1.Proxy Proxy 可以对目...

  • ES6 温故知新 Set & Map

    Set ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 Set 在 ES...

网友评论

      本文标题:温故知新之ES6(一)

      本文链接:https://www.haomeiwen.com/subject/buqhgftx.html