分解構造(destructing)

7845 ワード


  • 「mdn」を参照
    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

  • その他多くのサイト
    https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/

  • 個人学習に用いる内容はmdnと同じである.

  • 構造分解割り当て構文はJavaScript式で、配列またはオブジェクトの属性を分解し、その値を各変数に含めることができます.
  • 1.構文

  • アレイ
  • var a,b,rest;
    [a,b] = [10,20]
    console.log(a); // 10
    console.log(b); // 20
    
    [a, b, ...rest] = [10, 20, 30, 40, 50];
    console.log(a); // 10
    console.log(b); // 20
    console.log(rest); // [30, 40, 50]
  • オブジェクト(重要!!!)
    -キー値に従い、順序(restを除く)を考慮しない.
  • ({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
    console.log(a); // 10
    console.log(b); // 20
    console.log(rest); // {c: 30, d: 40}
    
    ({f, g, ...rest} = {a: 10, b: 20, c: 30, d: 40});
    console.log(f); // undefined
    console.log(g); // undefined
    
    ({b, a, ...rest} = {a: 10, b: 20, c: 30, d: 40});
    console.log(b); // 20
    console.log(a); // 10

    2.説明

  • 構造分解割当は、元の変数でどの値が分解されるかを定義するために、割当文の左側で使用されます.
  • var x = [1, 2, 3, 4, 5];
    var [y, z] = x;
    console.log(y); // 1
    console.log(z); // 2

    3.分解配列構造


    3.1デフォルト変数の割当て

    var foo = ["one", "two", "three"];
    var [one, two, three] = foo;
    console.log(one); // "one"
    console.log(two); // "two"
    console.log(three); // "three"
    
    만약 var one, two, three = foo; 할시
    console.log(one); // undefined
    console.log(two); // undefined
    console.log(three); // ["one", "two", "three"]

    3.2宣言から分離された割当て

  • 変数の宣言が分離されても、構造を分解することによって値を割り当てることができます.
  • var a, b;
    
    [a, b] = [1, 2];
    console.log(a); // 1
    console.log(b); // 2

    3.3デフォルト

  • 変数にデフォルト値を指定すると、分解値が定義されていない場合に使用されます.
  • var a, b;
    
    [a=5, b=7] = [1];
    console.log(a); // 1
    console.log(b); // 7

    3.4変数値の交換


    2つの変数の値を交換するには、
  • の構造分解式を使用します.
  • 構造分解を割り当てずに2つの値を交換するには、一時変数が必要です.
  • var a = 1;
    var b = 3;
    
    [a, b] = [b, a]
    console.log(a); // 3
    console.log(b); // 1
    

    3.5関数が返す配列解析

  • 関数は、以前から配列を返すことができます.構造分解を使用すると、返されるアレイをより簡潔に処理できます.
  • function f(){
      return [1,2];
    }
    
    var a,b
    [a,b] = f()
    console.log(a) // 1
    console.log(b) // 2

    3.6一部の戻り値を無視

    function f(){
      return [1,2,3]
    }
    
    var [a, ,b] = f()
    console.log(a) // 1
    console.log(b) // 3

    3.7変数に配列の残りの部分を割り当てる

  • アレイを分解する場合、残りの構文を使用して分解し、残りの部分を変数に割り当てることができます.
  • var [a, ...b] = [1,2,3]
    console.log(a) // 1
    console.log(b) // [2,3]
    
    var [a, b, ...c] = [1,2,3]
    console.log(a) // 1
    console.log(b) // 2
    console.log(c) // [3]

    3.8正規表現に一致する値を分解する

  • 正規表現のexec()メソッドは、一致する部分が見つかった場合、正規表現のすべての一致部分(配列の一番前にある)と、正規表現のカッコで囲まれた各グループに一致する部分を含む配列を返します.構造分解配分が不要な場合は、一致するすべての部分を無視して、必要な部分だけを簡単に取り出すことができます.
  • function parseProtocol(url) {
      var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
      if (!parsedURL) {
        return false;
      }
      console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]
    
      var [, protocol, fullhost, fullpath] = parsedURL;
      return protocol;
    }
    
    console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https"

    4.分解対象構造


    4.1デフォルトの割当て(毎回忘れる)

    var obj = {p:42, q:true}
    var {p, q} = obj;
    
    console.log(p); // 42
    console.log(q); // true
    次の例のようにキー値や他の変数名を使用することはできません.
    var obj = {p:42, q:true}
    var {a, b} = obj;     
    
    console.log(a); // undefined
    console.log(b); // undefined
    

    4.2アサイメントの宣言なし(エラーが発生しやすい部分)

    var a, b;
    
    ({a, b} = {a: 1, b: 2});

  • 割付文の周囲(...)は、オブジェクト文字(object literal)を使用して宣言されていない非構造化割り当てを行う場合に必要な構文です.

  • {a,b}={a:1,b:2}は有効な独立文法ではない.左側のオブジェクト文字ではないブロック(?)それはと見なされているからです.
    しかし,({a,b}={a:1,b:2})はvar{a,b}={a:1,b:2}のように有効である.

  • ( .. ) 式の前にセミコロンが必要です.それ以外の場合は、関数を実行するために前の行に関連付けることができます.
  • 4.3新しい変数名に65379;」を割り当てる

  • オブジェクトから属性を分解し、オブジェクトの元の属性名に異なる変数を割り当てることができます.
  • var obj = {p:42, q:true};
    var {p:foo, q:bar} = obj
    
    console.log(foo) // 42
    console.log(bar) // true

    4.4デフォルト

  • オブジェクトから解放された値が定義されていない場合は、変数のデフォルト値を指定できます.
  • var {a=10, b=5} = {a:3};
    
    console.log(a) // 3
    console.log(b) // 5

    4.5デフォルト値を持つ新しい名前変数への割り当て

    var { a: aa=5 b:bb=5} = {a:3};
    
    console.log(aa); // 3
    console.log(bb); // 5

    4.6ネストされたオブジェクトと配列の構造を分解する

    var metadata = {
      title : "Scratchpad"
      translations : [
        {
          locale : "de",
          localization_tags : [],
          last_edit : "2014-04-14T08:43:37",
          url : "/de/docs/Tools/Scratchpad"
          title : "JavaScript-Umgebung"
        } ],
      url : "/en-US/docs/Tools/Scratchpad"
    };
    
    var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
    
    console.log(englishTitle); // "Scratchpad"
    console.log(localeTitle); // "JavaScript-Umgebung"

    4.7繰り返し質問文と構造分解に使用できる」

    var people = [
      {
        name : 'Mike Smith',
        family : {
          mother : 'Jane Smith',
          father : 'Harry Smith',
          sister : 'Samantha Smith'
        },
        age : 35
      },
      {
        name : 'Tom Jones',
        family : {
          mother : 'Norah Jones',
          father : 'Richard Jones',
          sister : 'Howard Jones'
        },
        age : 35
      }
      ];
      
      for (var {name: n, family: { father: f } } of people) {
      console.log('Name: ' + n + ', Father: ' + f);
    }
    
    // 'Name: Mike Smith, Father: Harry Smith'
    // 'Name: Tom Jones, Father: Richard Jones'

    4.8関数パラメータを使用して渡されたオブジェクト分解フィールド

    function userId({id}){
      return id;
    }
    
    function whois({displayName : displayName, fullName : {firstName : name}}){
      console.log(displayName + ' is ' + name);
    }
    
    var user = {
      id : 42,
      displayName : 'jdoe',
      fullName : {
        firstName : 'John',
        lastName : 'Doe'
      }
    };
    
    console.log('userId: ' + userId(user); // 'userId: 42"
    whois(user) // 'jdoe is John'

    4.9計算された属性名と構造分解

  • で計算された属性名(computed property name)は、オブジェクト文字に類似した構造分解にも使用できます.
  • let key = 'z';
    let { [key]:foo} = {z:'bar'};
    
    console.log(foo) // 'bar'

    4.10対象構造分解における再テスト

    let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
    a; // 10
    b; // 20
    rest; // { c: 30, d: 40 }

    4.11属性名は有効なJavaScript識別子ではありません。

  • 分解構造は、提供される属性名がJavaScript識別子名に適用されない場合に使用することができる.有効な識別子を指定する必要があります.
  • const foo = {'fizz-buzz':true};
    const {'fizz-buzz':fizzBuzz} = foo;
    
    console.log(fizzBuzz) // true