ES 6の新特性

26877 ワード

ES 6、フルネームECMAScript 6.0、205.06リリース.ES 6は主にES 5の先天的な不足を解決するためです.例えば、JavaScriptには類の概念がありません.しかし、現在のブラウザのJavaScriptはES 5バージョンです.ほとんどの高バージョンのブラウザもES 6をサポートしていますが、ES 6の部分的な特性と機能だけを実現しました.
普段はプロジェクトの開発も長くかかりますが、今は全体的に復習しています.
1、let、const、blockのスコープ
letはブロックレベルのスコープ(一番近い括弧内で有効)を作成することができます.変数の昇格を備えていません.ステートメントを繰り返してはいけません.
//      
{
  let a = 1
  console.log(a)  // 1
}
console.log(a) // Uncaught ReferenceError: a is not defined

//      
{
  console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
  let a = 1
}

//       
{
  let a = 1
  let a = 2 // Uncaught SyntaxError: Identifier 'a' has already been declared
}
コンサート ブロックレベルのスコープを作成することができます.(一番近い括弧内で有効です.)変数宣言はアップグレードされません. 宣言時には必ず割り当てられ、宣言時には大文字の変数(標準規則):
//      
{
  const A = 1
  console.log(A)
}
console.log(A) // Uncaught ReferenceError: A is not defined

//      
{
  console.log(A) // Uncaught ReferenceError: Cannot access 'A' before initialization
  const A = 1
}

//        
{
  const A // Uncaught SyntaxError: Missing initializer in const declaration
}
2、矢印関数
ES 6では、矢印関数は関数の簡略形式であり、括弧でパラメータを包み、続いています. =>,続いて関数体です.
// ES5  
var getPrice = function() {
  return 4.55;
};
 
// ES6      ,   return  
var getPrice = () => 4.55;
矢印関数には、this変数の変更が含まれていません.
// ES5
function Person() {
  this.age = 0;
 
  setInterval(function growUp() {
    //        ,growUp()     this    window   
    this.age++;
  }, 1000);
}
var person = new Person();

// ES6
function Person(){
  this.age = 0;
 
  setInterval(() => {
    // |this|    person   
    this.age++;
  }, 1000);
}
 
var person = new Person();
3、関数パラメータのデフォルト値
ES 6において、関数パラメータのデフォルト値を設定することができます.
// ES5
var getFinalPrice = function (price, tax) {
  tax = tax || 0.7
  return price + price * tax;
}

// ES6
var getFinalPrice = function (price, tax = 0.7) {
  return price + price * tax;
}
4、Spread/Reset操作子
Spread/Resetオペレータとは演算子のことです.
// Spread,         
function foo(x,y,z) {
  console.log(x,y,z);
}
 
let arr = [1,2,3];
foo(...arr); // 1 2 3

// Rest,         
function foo(...args) {
  console.log(args);
}
foo( 1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]
5、対象語法の拡張
ES 6は、オブジェクトの字面量を宣言する際に、簡潔な文法を使用して属性変数と関数の定義方法を初期化し、オブジェクト属性の中での計算を許可する.
function getCar(make, value) {
  return {
    //     
    make,  //     make: make
    value, //     value: value

    //             
    ['make' + make]: true,

    //    `function`          
    depreciate() {
      this.value -= 2500;
    },
    // ES5  
    depreciateBak: function () {
      console.log(this['make' + this.make])
    }
  }
};
6、バイナリと八進法の字面量
ES 6はバイナリと8進数の字面量をサポートしています.数字の前に0 oまたは0 Oを追加することで8進数に変換できます.
let oValue = 0o10;
console.log(oValue); // 8
 
let bValue = 0b10; //       `0b`    `0B`
console.log(bValue); // 2
7、オブジェクトと配列の構造
オブジェクトの割り当て時に中間変数が生成されないように構成できます.
let obj = { a: 1, b: 2, c: 3 }
let { a: a1, b: b1, c: c1 } = obj
console.log(a1, b1, c1) // 1 2 3
// let { a, b, c } = obj //     
// console.log(a, b, c) // 1 2 3

let arr = [1, 2, 3]
let [d, e, f] = arr
console.log(d, e, f) // 1 2 3
8、オブジェクトスーパークラス
ES 6は、オブジェクトにsuper方法を使用することを許可する.
var parent = {
  foo() {
    console.log("Hello from the Parent");
  }
}
var child = {
  foo() {
    super.foo();
    console.log("Hello from the Child");
  }
}
Object.setPrototypeOf(child, parent); // child.__proto__ = parent
child.foo(); // Hello from the Parent
             // Hello from the Child
9、テンプレート文法とセパレータ
非常に簡潔な方法で文字列と変数の山を組み立てる.
let user = 'Barret';
// ``     ,${ ... }        
console.log(`Hi ${user}!`); // Hi Barret!
10、for…of VS for…in
for...ofは配列のような1つを巡回するために使用されます.
let nicknames = ['di', 'boo', 'punkeye'];
nicknames.size = 3;
for (let nickname of nicknames) {
  console.log(nickname);
}
//   : di, boo, punkeye
for...inはオブジェクト内の属性を巡回するために使用されます.
let nicknames = ['di', 'boo', 'punkeye'];
nicknames.size = 3;
for (let nickname in nicknames) {
  console.log(nickname);
}
// 0, 1, 2, size
11、Map VS WeakMap
ES 6の2つの新しいデータ構造セット:MapとWeakMap.実際にはどのオブジェクトもMapと見なされます.
一つのオブジェクトは複数のkey-valペアで構成されており、Mapでは、どのタイプも対象とするkeyがあります.
var myMap = new Map();
 
var keyString = "a string",
    keyObj = {},
    keyFunc = function () {};
 
//    
myMap.set(keyString, "value   'a string'   ");
myMap.set(keyObj, "value   keyObj   ");
myMap.set(keyFunc, "value   keyFunc   ");
 
myMap.size; // 3
 
//    
myMap.get(keyString);    // "value   'a string'   "
myMap.get(keyObj);       // "value   keyObj   "
myMap.get(keyFunc);      // "value   keyFunc   "
WeakMap Mapです.ただ、keyは全部弱いです.つまりWeakMapの中のものはごみを回収する時は考慮しないという意味です.メモリ漏れの心配がないです.
もう一つの注意点は、WeakMapのすべてのkeyは対象でなければなりません.それは4つの方法しかありません.delete(key)、has(key)、get(key)、set(key、val):
let w = new WeakMap();
w.set('a', 'b'); 
// Uncaught TypeError: Invalid value used as weak map key
 
var o1 = {},
    o2 = function(){},
    o3 = window;
 
w.set(o1, 37);
w.set(o2, "azerty");
w.set(o3, undefined);
 
w.get(o3); // undefined, because that is the set value
 
w.has(o1); // true
w.delete(o1);
w.has(o1); // false
12、セットVS WeakSet
Setオブジェクトは重複しない値のセットです.重複した値は無視されます.値の種類は元のタイプと参照のタイプとすることができます.
let mySet = new Set([1, 1, 2, 2, 3, 3]);
mySet.size; // 3
mySet.has(1); // true
mySet.add('strings');
mySet.add({ a: 1, b:2 });
Setオブジェクトに基づく値は重複しません.つまり、非常に便利な配列再除去方法があります.
//   Set     
let mySet = new Set([1, 1, 2, 2, 3, 3]);
// mySet => Set(3) {1, 2, 3}
// Object.prototype.toString.call(mySet) // [object Set]

let toArray = Array.from(mySet) // [1, 2, 3]
Object.prototype.toString.call(toArray) // [object Array]
オブジェクトをforEachとfor...ofで巡回できます.
mySet.forEach((item) => {
  console.log(item);
    // 1
    // 2
    // 3
    // 'strings'
    // Object { a: 1, b: 2 }
});
 
for (let value of mySet) {
  console.log(value);
    // 1
    // 2
    // 3
    // 'strings'
    // Object { a: 1, b: 2 }
}
Setにはdelete()とclear()の方法があります.
WeakMapに似ています.WeakSetオブジェクトは、1つのセットにオブジェクトを保存する弱い参照を許可します.WeakSetのオブジェクトは一回だけ表示されます.
var ws = new WeakSet();
var obj = {};
var foo = {};
 
ws.add(window);
ws.add(obj);
 
ws.has(window); // true
ws.has(foo);    // false, foo       
 
ws.delete(window); //        window   
ws.has(window);    // false, window        
13、クラス
ES 6にはクラス文法があります.ここのクラスは新しい対象継承モデルではなく、プロトタイプチェーンのシンタックスキャンディー表現形式です.
関数でstaticキーワードを使って構造関数を定義する方法と属性:
class Task {
  constructor() {
    console.log("task instantiated!");
  }
  showId() {
    console.log(23);
  }
  static loadAll() {
    console.log("Loading all tasks..");
  }
}
 
console.log(typeof Task); // function
let task = new Task(); // "task instantiated!"
task.showId(); // 23
Task.loadAll(); // "Loading all tasks.."
クラスの継承とオーバーセット:
class Car {
  constructor() {
    console.log("Creating a new car");
  }
  call(val) {
    console.log('parent --->', val)
  }
}

class Porsche extends Car {
  constructor() {
    super();
    console.log("Creating Porsche");
    super.call('inner')
  }
  call2(val) {
    super.call(val)
  }
}

let c = new Porsche();
c.call2('outer')

// Creating a new car
// Creating Porsche
// parent ---> inner
// parent ---> outer
extensは、サブクラスの親クラスを継承することができます.サブクラスのconstructor関数ではsuper()関数を実行する必要があります.
もちろん、super.parent MethodName()のように、サブタイプの方法で父親タイプの方法を呼び出すこともできます.
いくつか注意すべき点があります.
  • 類の声明はアップグレードされません.もしあるクラスを使うなら、使う前に定義しなければなりません.そうでなければ、ReferenceErrerのエラーを投げます.
  • クラスで関数を定義するには、Fnctionキーワードを使用する必要はない
  • 14、Symbol
    Symbolは新しいデータタイプで、その値は唯一で、可変ではない.ES 6でsmbolを提案する目的は一意の識別子を生成するためであるが、この識別子にアクセスできない:
    var sym = Symbol( "some optional description" );
    console.log(typeof sym); // symbol
    なお、ここではSymbolの前でnewオペレータは使用できません.
    オブジェクトの属性として使用されると、この属性は列挙できません.
    //   Symbol      
    Symbol(1) == Symbol(1) // false
    
    let ran = Symbol("random")
    var o = {
      val: 10,
      [ran]: "I'm a symbol",
    };
    
    console.log(Object.getOwnPropertyNames(o)) // val
    console.log(o[ran]) // "I'm a symbol"
    15、シーズムレータ(Iterators)
    シーズマリーは、データのセットの各要素にアクセスすることを許可します.ポインタがデータのセットの最後の要素を指すと、シーズマリーは終了します.next関数を提供して、シーケンスを巡回します.この方法はdoneとvalue属性を含むオブジェクトを返します.
    ES 6では、Symbol.iteratorを通じてオブジェクトにデフォルトのエルゴードを設定することができます.オブジェクトが遍歴される必要があるときはいつでも、その@@iterator方法を実行すると、値を取得するためのローズマリーを返すことができます.
    配列のデフォルトは、次の順序です.
    var arr = [11,12,13];
    var itr = arr[Symbol.iterator]();
     
    itr.next(); // { value: 11, done: false }
    itr.next(); // { value: 12, done: false }
    itr.next(); // { value: 13, done: false }
     
    itr.next(); // { value: undefined, done: true }
    オブジェクトを[Symbol.iterator]()でカスタマイズすることができます.
    16、Generators
    Generator関数はES 6の新しい特性であり、一つの関数が返したエルゴードオブジェクトが複数の値を生成することができます.
    使用中に*文法と新しいキーワードyieldが見られます.
    function *infiniteNumbers() {
      var n = 1;
      while (true){
        yield n++;
      }
    }
     
    var numbers = infiniteNumbers(); // returns an iterable object
     
    numbers.next(); // { value: 1, done: false }
    numbers.next(); // { value: 2, done: false }
    numbers.next(); // { value: 3, done: false }
    yieldを実行するたびに返される値は、次の数値となります.
    17、Promise
    ES 6はPromiseに対して原生の支持を持っています.一つのPromiseは非同期で実行される対象です.実行が完了すると、その状態はresovedまたはrejectになります.
    var p = new Promise(function(resolve, reject) {  
      if (/* condition */) {
        // fulfilled successfully
        resolve(/* value */);  
      } else {
        // error, rejected
        reject(/* reason */);  
      }
    });
    
    p.then((val) => console.log("Promise Resolved", val),
           (err) => console.log("Promise Rejected", err));
    18、ProxyとReflect
    Proxyは、対象オブジェクトの読み込みや関数呼び出しなどの操作をブロックして、直接的にオブジェクトを操作するのではなく、プロキシモードのようにオブジェクトのプロキシオブジェクトを介して操作し、これらの操作を行う際に必要な追加操作を行うことができます.
    Reflectはターゲットオブジェクトを取得するための動作に使用できます.Objectと似ていますが、より読みやすく、操作対象によりより優雅な方法を提供します.その方法はProxyに対応しています.
    Proxyの詳細はここで注文します.
    Reflectの詳細はここで注文します.
    19、文字列
    ES 6の文字列操作方法の拡張.
  • includes():ブール値を返し、パラメータ文字列が見つかったかどうかを判断する.
  • starts With():ブール値を返し、パラメータ文字列が元の文字列の先頭にあるかどうかを判断する.
  • endsWith():ブール値を返し、パラメータ文字列が元の文字列の末尾にあるかどうかを判断する.
  • repeat():新しい文字列を返し、文字列を指定回数繰り返すことを表します.
  • padStart:新しい文字列を返し、パラメータ文字列でヘッダ(左側)から元の文字列を補完することを表します.
  • padEnd:新しい文字列を返します.パラメータ文字列で末尾(右側)から元の文字列を補完することを表します.
  • 20、モジュール
    ES 6の前にモジュール化を実現するには、RequireJSまたはseaJS(それぞれAMD仕様に基づくモジュール化ライブラリであり、  及びCMD規格に基づくモジュール化ライブラリ).
    ES 6はモジュール化を導入しており、その設計思想はコンパイル時にモジュールの依存関係、および入出力の変数を確定することができます.
    ES 6のモジュール化は、導出(export)@と導入(import)の二つのモジュールに分けられます.
    exportとimport:
  • によって導出された関数ステートメントとクラスステートメントには名前が必要です. 
  • は、声明を導き出すだけでなく、参照(例えば関数)を導き出すことができる.
  • exportコマンドは、モジュールの任意の位置に存在することができますが、モジュールの最上位にある必要があります.
  • importコマンドは、モジュール全体のヘッダに引き上げられます.まず実行します.
  • asの使い方:
    exportコマンドが導き出すインターフェースの名前は、モジュール内部の変数と一対一の対応関係があります.導入した変数名は、導き出すインターフェースの名前と同じでなければなりません.つまり、順序は一致しません.asを使用してください. エクスポートしたインターフェース名を再定義し、モジュール内部の変数を非表示にします.
    export defaultコマンド:
  • は、1つのファイルまたはモジュールの中で、export、importは複数あってもよく、export defaultは1つだけあります.
  • export defaultは対応する導出インターフェース変数です.
  • export方式でエクスポートし、導入時に「-」、export defaultを追加する必要はありません.
  • export defaultが外部に露出したメンバーは、任意の変数を使用して受信することができます.
    21、async/await
    asyncはES 7ならではの非同期操作に関するキーワードで、Promise、Generatorと大きく関連しています.
    async関数はPromiseオブジェクトを返します.then法を使ってコールバック関数を追加できます.
    async関数にはawait表現があるかもしれません.async関数が実行されている場合、awaitが発生したら、先に実行を停止します.トリガの非同期操作が完了したら、async関数の実行を再開し、解析値を返します.
    awaitキーワードはasync関数内でしか有効でないので、エラーが発生します.awaitはPromiseオブジェクトの処理結果に戻ります.待っているのがPromiseオブジェクトでないなら、その値自体に戻ります.Promiseがawait操作子に渡されたら、awaitはPromise正常処理が完了したら、その処理結果に戻ります.
    awaitとは異なる表現に対する扱い方:
  • Promise対象:awaitは実行を一時停止します.待ちます. Promiseオブジェクトresoveは、async関数の実行を再開し、解析値を返します.
  • 非Promiseオブジェクト:直接に対応する値を返します.
  •  
    元の鳥:https://www.runoob.com/w3cnote/es6-concise-tutorial.html