javascriptのtoString()とvalueOf()関数

6566 ワード

1.私たちはなぜこの二つの方法を知っていますか?
    ご存知のように、tostring関数とvalueOf関数は、Object類のオブジェクトが生まれつき持っています.また、書き換えることができます.この2つの関数はいったい何の役に立つのでしょうか?
名前から判断します.toString()は対象を文字列に変換し、valueOfは対象を値に変換します.問題があります.対象をいつ値に変換する必要がありますか?またいつ文字列に変換する必要がありますか?これは私たちのこの文章の核心です.
   この問題を話す前に、まずテーマを見ます.       
   これは経典的なテーマです.考察するのは私達がいくつかの基本的な概念についての理解です.もちろん難しい問題です.
  javascript ,   var  a= add(1)(2)(3)(4)(5);  // 5 ,15------------ http://dmitry.baranovskiy.com/post/31797647
var add = function (n) {

  var result = n;

  var func1 = function (m) {

    result += m;

    return func1;

  }

  func1.toString = function () {

    return result.toString();

  }//     toStrig  

  func1.valueOf = function () {

    return result;

  }//     valueOf  

  

  return func1;

}

var a = add(1)(2)(3)(4)(5);

console.log(a);//15

console.log(a+10)//25



  

  
上のテーマはそう簡単には考えられません.また、一般的にはプログラマーもこのような自分で見ても違和感のあるコードを書かないようにしています.私たちはただこれによっていくつかの基本的な概念を説明するだけで、この文章の存在の必要性です.
上記の例から、出力時にFunctionタイプからStringタイプへの変換を伴うことが分かる.この変換はどうやって発生しますか?第二部分では、満足できる説明をします.
 
 まず、私たちは一つのことを知る必要があります.toStringとvalueOfの二つの関数は、解釈器が私たちの自動的にタイプ間の変換(一般的には対象から基本タイプへの変換)を完成させ、さらに満足できる結果を出力します.
 
2.基本データタイプへのオブジェクト変換のルール
 (1)vauleOfがtoString()より優先的に呼び出された場合-----対象が操作数である場合(Dateタイプの場合を除く)
まず、下の操作を見てみます.データタイプの変換です.
  var x="10";

  

  var a=+x;

  console.log(typeof a);     //number

  

  

  var b=a+x;

  console.log(typeof b);    //string
上に挙げたのは私が挙げた3つのタイプの変換だけで、最も基本的な概念でもあります.この3つのタイプの変換はどのように行われていますか?
3-4行: 「+」は、1要素演算子として使用されます.この演算子の下で、オブジェクトの基本データタイプへの変換規則:
              (1)動作数が基本データタイプの場合は、Number()関数を呼び出し、値に変換します.
                (2)動作数が対象の場合は、オブジェクトのtoStringまたはvalueOf関数を呼び出し、オブジェクトを基本データタイプの値に変換して、その値に対してNumber()関数を呼び出します.
 
 以上の変換規則により、上記の出力結果がnumberであることが妥当である.
 しかし、第二条の変換規則には、tostringを呼び出すか、それともvalueOfを呼び出すか、どちらの関数でも対象を基本的なデータタイプに変換できるという大きな穴が含まれています.
  以下のように:
var x = {

  toString: function () {

    return '0';

  },

  valueOf: function () {

    return 1;

  }

}

var a = + x;  //    ,      toString()  valueOf() ?,  +            ,     

console.log(a);
1
 1
7-8行:「+」は二元演算子として使用されます---. この演算子の下で、オブジェクトの基本データタイプへの変換規則
   「+」が2元の演算子である場合は複雑です.「+」は文字列の接続としてもいいし、数字の加算としてもいいです.変換規則を調べてもいいです.7、8条もあります.見ている人は目がくらみます.大量のテストを経て、いくつかの資料を調べて、以下の規則をまとめました.
//   ,

a + b      :
var Pa=toPrimitive(a)var pb=toPrimitive(b) try{  if((Pa is String)𞓜(Pb is String)){      return contact(String(Pa)、String(Pb));     } else{      return Number(Pa)+Number(Pb);     }    } catch(e){      throw e;  }
 // : toPrimitive               ,    valueOf,         ,   ,      toString()。(    valueOf      toString())
  これらをよく知っていると、+番号は1元の演算子として変換される規則と、2元の演算子として同じぐらいで、基本的なデータタイプに変換するときは常に優先的にvalueOf()を呼び出していることがわかります.以下の例で検証します.
 var test = {

   valueOf: function () {

     return 1;

   },

   toString: function () {

     return '0';

   }

 }

 console.log( + test);   //1

 var result = test + test;

 console.log(result);  //2
 以上のようにまとめて結論を出すことができます.オペランド演算の場合(一元でも二元でも)、データタイプ間の変換は常に優先的にvalueOf()関数を呼び出すのですが、「+」は二元演算子としてDateタイプのオブジェクトに適用されるとき、逆転されます.
   メモ:Dateタイプは特例であり、+番号演算のみであり、+番号が二元演算子である場合、toString()は、以下のように優先的に呼び出します.
var date=new Date();



console.log(+date);  //      valueOf  

console.log(date+"toString     ");
 
//    :
// 1421293488713
//Thu Jan 15 2015 11:44:48 GMT+0800toString
 
(2):toString()valueOf()より優先的に呼び出された場合――出力したい結果が文字列である場合  
Objectタイプのオブジェクトにアクセスする変数は、このような四角い括弧でアクセスすると、四角い括弧の内容は常に優先的に文字列に変換されます.すなわち、tostring()関数を優先的に呼び出します.以下の例を見てください.
 var test = {

   toString: function () {

      return '0'

    },

    valueOf: function () {

      return 1;

    }

  };

  

 var object={};

 object[test]=1000;

 console.log(object);  //     :Object{0=1000}
この場合の呼び出しの原則は以下の通りです.
[a]          :

var Pa=toPrimitive(a);
if(Pa is prmitive){
    var str=String(Pa);
    }else{
throw error;//cannot convert to string
    }
[str]//str       
   // : toPrimitive() toString() , , , valueOf(); 
 
いくつかのtoStringがvalueOf()より優先的に呼び出された例があります.
var test = {

  toString: function () {

    return '0'

  },

  valueOf: function () {

    return 1;

  }

};



alert(test); //    toString()    0

  
 
var test = {

  toString: function () {

    return '0'

  },

  valueOf: function () {

    return 1;

  }

};

var test1 = {

  toString: function () {

    return '0'

  },

  valueOf: function () {

    return 1;

  }

}

var array = [

  test,

  test1

];

console.log(array + '')





//           :



 //1.array+" "       ,    array.valueOf()  ,            

 //2.    array.toString()  。     Array    ,   ,         

   //    toString()  ,     valueOf()  。(            ,      )



 ,            toString

  
 3.なぜこれらの奇妙な現象が現れたのですか?
    上記からわかるように、tostringとvalueOfの二つの関数は変換時に呼び出される可能性があります.ただ異なる環境で呼び出される優先度が違っています.これらは私たちプログラマにとっては透明かもしれませんが、解釈器にとっては、より多くの仕事をすることができます.一言で説明します.解凍器はいつも文脈によってできるだけ転化されます.私たちが欲しい結果.言い換えれば、
 
 オブジェクトは操作数として、常に優先的にvalueOf()-(Dateタイプのオブジェクトは2元の「+」演算時に例外)を呼び出しますが、他の場合、解釈器はいつも私たちが欲しいのは文字列だと考えていますので、tostring()を優先的に呼び出します.
 注:Dateタイプのオブジェクトが、2元+演算時にToString()を優先的に呼び出すのは、時間がいつも文字列と接続して使用しているためであり、時間と1つの数字が加算される場合が少ないため、Dateタイプのうち、toString()優先順位が比較されます.       高いです
 
 このような乱雑な現象や規則が現れるのは、解釈器が完璧に出力したいからです.天下には完璧なものがありません.矛と盾はいつも寄り添っています.
 ルールを知ってこそ、ルールを利用して、最初に出したテーマを振り返ってみましょう.これらのルールを合理的に利用することですか?
 
 
 
                    余談:この文章を書くということは、基礎知識の重要性を示すためであり、奇妙な手順を追求するのではなく、プログラマが求めるべきは分かりやすいコード(大道至簡)であって、これらの見たところ似ていないプログラムではなく、本末転倒である.
                                  その他に、これらを見終わった後に再び本を読む衝動があるのではありませんか?もしあるならば、私の目的は達成しました.ははは!
備考:toLocareStering()という関数は文字列のローカライズを実現する出力です.一般的にtoStering()の出力と同じです.特別なものはなく、普通の関数です.Dateタイプでは、この関数は書き換えられました.