私はグループの中でシャオ・ファンファンと名乗る90歳のかわいい青年と話をしていたところ、IT関連の人々の悪い習慣について話したところ、シャオ・ファンファンが突然尋ねました。
1. の変数を宣言します。数値型を確認しました。 3 つのタイプがあります。違いは何ですか:
オールドルーキー特有の遠慮とプライドを持って、私は軽蔑的にこう言いました。「そんなことは知りません。自分で調べてください。」 。 。向きを変えて、ECMAS - 262 (第 5 版) をめくってください。
1. 数値型変数を宣言する 5 つの方法
//方法 1: 最も一般的な方法は、数値リテラルを介して宣言します
var num = 123; //方法 2: 時折使用され、ほとんどの場合、文字列を数値に変換するために使用されます
var num = Number(123)
//方法 3: めったに使用されませんが、Rhinoceros Books を含むさまざまな神聖な書籍にリストされています。非推奨メソッド
var num = new Number(123);
//メソッド 4: 神のメソッド、まだ誰も使っていません
var num = new Object(123) ); 🎜>//方法 5: さらに奇妙で奇妙な
var num = Object(123);
上記の 5 つの宣言方法のうち、方法 1 は言うまでもなく通常は次のように使用されますが、方法 3 から方法 5 は比較のために使用されます。
1.5 とは2 つの宣言方法の違いは何ですか?震える指でコードを入力したとき、何が起こりましたか?
2. メソッド 1 で宣言されているものは明らかにオブジェクトではありませんが、通常、toString などのメソッドを呼び出すことができるのはなぜですか?
2. さまざまな宣言方法の違い
方法 1: var num = 123;
EC5 の説明:
数値リテラルは Number の値を表します。この値は 2 つのステップで決定されます。まず、数学的値 (MV) がリテラルから導出されます。次に、この数学的値が以下のように丸められます。
//....個人的な要約の概要:
1. 数値の宣言方法は num = .123、num = 123e4 などの形式にすることもできるため、整数部分、小数部分を取り出すなど、変数の値を解析します。
2解析された値を近似します。例: num = 123.33333333333333...333333333333333333333333.... このとき、近似値を取得する必要があります。特定の近似値を使用すると、ルールは拡張されません。この方法で宣言された変数は単なる数値リテラルであり、オブジェクトではありません (なぜ toString や他のメソッドを呼び出せるかについては、後ほど説明します)
メソッド 2: var num = Number( 123)
; EC5 の説明:
15.7.1 関数として呼び出される Number コンストラクター
Number がコンストラクターとしてではなく関数として呼び出される場合、型変換が実行されます。 Number ( [ value ] )
値が指定された場合は ToNumber(value) によって計算された Number 値 (Number オブジェクトではない) を返し、それ以外の場合は 0 を返します。 個人的な要約の概要:
ここで Number は単に an として呼び出されます。コンストラクターではなく通常の関数なので、返されるのはオブジェクトではなく、単純な値です。
2. 本質はメソッド 1 と同じです。メソッド 1 との違いは、メソッド 1 に基づいて異なる型変換処理を実行する必要があることです。受信パラメータの型に応じて、パラメータを対応する値に解析します。具体的なルールは次のとおりです:
方法 3: var num = new Number(123)
; EC5 の説明:
15.7.2 Number コンストラクター
Number が新しい式の一部として呼び出される場合、これはコンストラクターです。15.7.2.1 new Number ( [ value. ] )
新しく構築されたオブジェクトの [[Prototype]] 内部プロパティは、元の Number プロトタイプ オブジェクト、つまり Number.prototype (15.7.3.1) の初期値である
The [[。
新しく構築されたオブジェクトの [[PrimitiveValue ]] 内部プロパティは、
が指定された場合は ToNumber(value) に設定され、そうでない場合は ToNumber(value) に設定されます。 0.
新しく構築されたオブジェクトの [[Extensible]] 内部プロパティは true.personal に設定されます。 概要:
1. ここで Number 関数コンストラクターが呼び出され、Number 型のオブジェクトが返されます。オブジェクトは Number のプロトタイプのプロパティとメソッドにアクセスできます。これは少し混乱するかもしれません。これについては後ほど説明します。
var num = new Number(123);
console.log(typeof num); //出力: object
console.log(Object. prototype.toString.call(num)); //出力: [オブジェクト番号]
3. 返される Number 型オブジェクト内の元の値 ([[PrimitiveValue]]) は、型変換後に取得される数値です。具体的な変換規則は、メソッド 2
メソッド 4: var num = new Object(123);
EC5 の説明: 15.2.2 オブジェクト コンストラクター
Object が新しい式の一部として呼び出される場合、それはコンストラクターです。
15.2.2.1 new Object ( [ value ] )
引数なし、または 1 つの引数値を指定して Object コンストラクターが呼び出される場合、次の手順が実行されます。
1.value が次の場合指定された場合、
a. Type(value) が Object の場合、
1. 値がネイティブ ECMAScript オブジェクトの場合、新しいオブジェクトを作成せず、単に値を返します。
b. Type(value) が String の場合、ToObject(value) を返します。 c. Type(value) が Boolean の場合、ToObject(value) を返します。d. Type(value) が Number の場合、ToObject(value) を返します。2.Assert: 引数の値が指定されていないか、その値が指定されていません。
3. obj を新しく作成したネイティブ ECMAScript オブジェクトにします。
4. obj の [[Prototype]] 内部プロパティを標準の組み込み Object プロトタイプ オブジェクトに設定します。 ).
5.obj の [[Class]] 内部プロパティを「Object」に設定します。
6. obj の [[Extensible]] 内部プロパティを true に設定します。 8.12 で指定されている obj の内部メソッド。
個人的な理解
:
上には多くのテキストが掲載されているため、頭が痛くなるかもしれません。 new Object(param) はこの方法で変数を宣言します。得られる結果は、データ型など、渡されたパラメータの特定の型に応じて異なります。ここでの特定の変換ルールは無視できます。現在の関係の部分、つまり、上で赤でマークされたテキストのみを確認します。
1. パラメーターが渡された場合、そのパラメーターは次のとおりです。数値の場合、Number 型オブジェクトを作成して返します - はい、実際にはメソッド 3
2 と同等です。 Number オブジェクトの値は渡されたパラメーターと等しく、内部の [[prototype]] 属性は Number を指します。 .prototype
メソッド 5: var num = Object(123);
EC5 の説明:
15.2.1 関数として呼び出されるオブジェクト コンストラクター オブジェクトがコンストラクターとしてではなく関数として呼び出される場合
15.2.1.1 Object ( [ value ] )
引数なし、または 1 つの引数値を指定して Object 関数を呼び出すと、次の手順が実行されます。
1.If value null、未定義、または指定されていない場合は、標準の組み込み Object コンストラクターが同じ引数 (15.2.2.1) で呼び出された場合とまったく同様に、新しい Object オブジェクトを作成して返します (15.2.2.1)。 🎜>
個人的な理解
:
1. 渡されたパラメータが空、未定義、または null の場合、新しいオブジェクト (param) と同等です。param はユーザーによって渡されたパラメータです
2. それ以外の場合は、オブジェクトが返されます。オブジェクト タイプは次の表に示されています。特に上記の例では、基本的に new Number(123) と同等です。 🎜>3. 単純なテスト ケース
コードをコピーします
コードは次のとおりです:
var num = Object(123); //出力: オブジェクト console.log(Object.prototype.toString.call(num)); // 出力: [オブジェクト番号]
コードをコピー
コードは次のとおりです:
var num = 123; console.log(num.toString(num)); //出力: '123'、エラーは発生しませんでした。 🎜>
Didn’t it mean that the literal declaration is just an ordinary numerical type, not an object? But the toString method call does not come from the object. This is unscientific!
Okay, I checked the Rhinoceros book and found the answer:
When the user declares a variable through literals and calls methods such as toString on the variable, the JS script engine will Secretly create a packaging object corresponding to the variable, and call the corresponding method on the object; when the call is completed, the object is destroyed; this process is invisible to the user, so many beginners will have this problem Puzzled.
Okay, I admit that the above paragraph is not the original text, it is just my personal understanding of the corresponding paragraph in the Rhinoceros book, and I deliberately added a quotation mark in order to appear more professional and authoritative. . . The example given above can be simply viewed as the following process:
var num = 123;
var tmp = num;
num = new Number(num);
console.log(num.toString(num));
num = tmp;
(Because I was flipping through the standard last night until almost 1 o'clock, I was really sleepy, so I was lazy. I believe Rhino Book will not trick me)
4. Write it at the back I have always felt unable to complain about Javascript’s variable declaration method, type judgment, etc. The above content is tantamount to ruining the outlook for beginners; even for someone like me who has been working with Javascript for two years Many veteran rookies are often confused
A brief summary:
1. Method one and method two are essentially the same
2. Method three, method four and method five are essentially the same
The last Finally:
If there are any errors or omissions in the examples in the article, please point them out; if you think the article is useful to you, you can click "Recommend" :)