部分1-3)オブジェクト:既定-8)オブジェクトを元に変換

18453 ワード


オブジェクトを元のオブジェクト部分に変換する:https://ko.javascript.info/object-toprimitive

オブジェクトを元のオブジェクトに変換


オブジェクト間で算術演算を追加または減算したり、alertメソッドを使用してオブジェクトを出力したりするとどうなりますか?=>自動変換が発生します.
オブジェクトを元の値に変換し、予想される演算を実行します.
  • オブジェクトは、論理評価時にtrueを返さなければなりません.したがって、オブジェクトは数値型または文字型変換としか見なされません.
  • 2.数値変換は、オブジェクト間の減算や数学的相関関数の適用時に発生します.Dateオブジェクト間の差(date 1-date 2)は、2つの日付の時間差を返します.
  • 文字フォーマットに変換することは、alert(obj)のようなオブジェクトを出力しようとするときに通常発生する.
  • ToPrimitive


    特殊なオブジェクトメソッドを使用すると、必要に応じて数値型と文字型の変換を実行できます.
    オブジェクト型変換は、「hint」と呼ばれる値を分割基準とする3つのタイプに分けられます.hint「何がリスト(https://tc39.es/ecma262/#sec-toprimitive)に詳しく説明されており、変換時に「ターゲットをターゲットとする資料型」が見られる.

  • string
    所望の文字列の演算(alert関数など)が実行されると(オブジェクト-文字列変換)、hintは文字列となる.

  • number
    数学演算を適用しようとすると(オブジェクト−デジタル変換)、hintはnumberとなる.

  • default
    演算子が望むデータ型は「不確定時」hintはdefaultです.
  • 例えば、この加算演算子+は、被演算子のデータ型に応じて文字列合成演算を行ってもよいし、数値加算演算を行ってもよい.したがって、+のパラメータがオブジェクトの場合、hintはdefaultになります.文字になるか数字になるかわからない
    等しい演算子==を使用してオブジェクト-文字型、オブジェクト-数値型、オブジェクト-エレメント型を比較すると、オブジェクトをなぜデータ型に変換するのか分からないため、hintはdefaultになります.
    <script>
      // 이항 덧셈 연산은 hint로 `default`를 사용
      let total = obj1 + obj2;
    
      // obj == number 연산은 hint로 `default`를 사용
      if (user == 1) { ... };
    </script>
    演算子<,>は、被演算子に文字型と数値型を同時に使用することも可能であり、これらの演算子のhintは「number」に固定されている.これは互換性が低いために制定されたルールです.
    実際、Dateオブジェクトを除いて、hintがdefaultとnumberの場合、すべての内蔵オブジェクトの処理方法は同じです.
    (すべてのオブジェクトがtrueとして計算されるため、hintにはブール型はありません.)
  • JavaScriptは、形状を変換する必要がある場合、以下のアルゴリズムに従って必要なメソッドを検索して呼び出す.(オブジェクト-元の変換)

  • オブジェクトにobj Symbol.toPrimitiveメソッドがあるかどうかを検索し、ある場合はメソッドを呼び出します.Symbol.toPrimitiveは、構成部品キーとして使用されるシステム構成部品です.

  • hintが1番ではなく「string」の場合.
    obj.toString()またはobj.valueOf()を呼び出します(存在するメソッドのみを実行します).

  • hintがnumberまたはdefaultでない場合、
    obj.値Of()またはobj.TOString()を呼び出します(存在するメソッドのみを実行します).
  • stringまたはnumberまたはdefaultはobjです.toString()またはobj.コールvalueOf()の違いは何ですか...
    obj Symbol.toPrimitiveメソッド=>hintが文字列=>hintが数値かデフォルトかを確認します.この三つの段階が核心だろう.

    Symbol.toPrimitive


    JavaScriptでSymbolを使用します.以下に示すように、ターゲットの名前を付けるデータ型(hint)用のtoPrimitiveという内蔵要素が存在します.
    obj Symbol.toPrimitive形態で使用される.
    <script>
      obj[Symbol.toPrimitive] = function(hint) {
        // 반드시 원시값을 반환해야 한다.
        // hint는 "string", "number", "default" 중 하나가 될 수 있다.
      };
      
      //------------------실제 동작 예시------------------
        let user = {
        name: "John",
        money: 1000,
    
    	//심볼을 프로퍼티로 쓸 때는 대괄호를 사용한다.
        [Symbol.toPrimitive](hint) {
          alert(`hint: ${hint}`);
          //형변환 목표 자료형이 string이면 name을 아니면 money를 반환
          return hint == "string" ? `{name: "${this.name}"}` : this.money;
        }
      };
    
        // 데모:
        alert(user); // hint: string -> {name: "John"}
        alert(+user); // hint: number -> 1000
        alert(user + 500); // hint: default -> 1500, 문자형이 될지 숫자가 될지
        //모르니까 default.
    </script>
    このように方法を実装すると,userはhintに基づいて文字列(name)に変換したり,数値(money)に変換したりすることができる.
    このように、user[Symbol.toPrimitive]を使用すると、すべてのタイプの変換を1つの方法で処理できます.

    toStringとvalueOf


    オブジェクト上のSymbol.TOPrimitiveがない場合、JavaScriptは、直接変換可能なtoStringまたはvalueOfを次のルールに従って呼び出します.
  • プロンプトがstringの場合:toString->valueOf順序(toStringがある場合はtoString、toStringがない場合はvalueOf)
  • その他:valueOf->toStringシーケンス
  • toStringメソッドとvalueOfメソッドは、元の値を返さなければなりません.
    この2つのオブジェクトが返されると、メソッドが最初から存在しないように、結果は無視されます.
    返される値がオブジェクトの場合は、次のようにtoString、valueOfに適用されるルールに従います.
  • toStringは、文字列「[objectObject]」を返します.
  • valueOfは、オブジェクト自体を返します.
  • <script>
      let user = {name: "John"};
    
      alert(user); 
      // [object Object] 반환. alert 함수가 대상을 string으로 형변환하니까.
      
      alert(user.valueOf() === user); 
      // true, valueOf는 반환값이 객체일 때 자기 자신을 반환하니까.
    </script>
    以上のように、toStringおよびvalueOfは、戻り値がオブジェクトである場合にエラーが発生することはなく、必要に応じて[objectObject]またはオブジェクト自体を吐き出すがSymbolである.toPrimitiveは元の資料を返さなければなりません.さもないと間違います!
    これらの方法を用いて上に見たSymbol.TOPrimitiveの使用例と同じ結果を生成できます.
    <script>
      let user = {
        name: "John",
        money: 1000,
    
        // hint가 "string"인 경우
        toString() {
          return `{name: "${this.name}"}`;
        },
    
        // hint가 "number"나 "default"인 경우
        valueOf() {
          return this.money;
        }
      };
    
      alert(user); // toString -> {name: "John"}
      alert(+user); // valueOf -> 1000
      alert(user + 500); // valueOf -> 1500
    </script>
    もしあなたがたまに1つの場所(1つの方法で)すべての変換を処理する必要があるならば?下図のように、toStringを実現するだけです.
    オブジェクト上のSymbol.toPrimitiveとvalueOfがない場合、toStringはすべてのタイプの変換を処理します.
    <script>
      let user = {
        name: "John",
    
        toString() {
          return this.name;
        }
      };
    
      alert(user); // toString -> John
      alert(user + 500); // toString -> John500
    </script>

    戻りタイプ


    しかし、実際には、上で紹介したSymbol.toPrimitive、toString、valueOfの3つの方法では、hintで指定されたデータ型への変換は保証されません.
    TOString()が常に文字列を返すことは保証されません.Symbol.TOPrimitiveのプロンプトが「number」の場合、常に数値型データを返す保証はありません.
    これらのメソッドは、オブジェクトではなく元の値を返すことを保証します.

    追加フォーマットのコピー


    かなりの演算子と関数変換は演算子の形式によって変換されます.(ex.*は演算子によって数値形式に変換されます)
    オブジェクトが被演算子の場合、オブジェクトは元のタイプに変換されます.元の値が必要なデータ型でない場合、再変換が発生します.
    <script>
      let obj = {
        // 다른 메서드가 없으면 toString에서 모든 형 변환을 처리.
        toString() {
          return "2";
        }
      };
    
      alert(obj * 2); 
      // 4, 객체가 문자열 "2"를 반환, 곱셈 연산 과정에서 문자열 "2"가 숫자 2로 변경된다.
    </script>
    上は乗算なので、文字2を数字2に変換するプロセスが発生しますが、加算演算子は文字列間に追加できるので、変換は少し異なります.
    <script>
      let obj = {
        toString() {
          return "2";
        }
      };
    
      alert(obj + 2); 
      // 22("2" + 2), 문자열이 반환되기 때문에 문자열끼리의 병합.
    </script>