2011-12-20 43 views
15

誰かが以下を説明できますか?インスタンスの不一致

[] instanceof Array; // true 
'' instanceof String; // false 
+1

また、 'typeof"は '' string ''であり、 'typeof []'は ''オブジェクト ''です(' '配列' 'は期待していますが、それでも問題ありません) – Halcyon

+0

''は原始的であるが、オブジェクトである? –

+2

興味深いのは、 "" "コンストラクタ=== String'です。 – pimvdb

答えて

14

以下注

"" instanceof String;    // => false 
new String("") instanceof String; // => true 

instanceofは、オブジェクトを必要とするが、""はリテラル文字列ではなく、文字列オブジェクトです。 typeof機能を使用して、次のタイプの点に注意してください。

typeof ""    // => "string" 
typeof new String("") // => "object" 
typeof []    // => "object" 
typeof new Array() // => "object" 
+0

'リテラル文字列'と 'String'オブジェクトの違いは何ですか?それはなぜ(明らかに)重要ですか?私が知る限り、それらは互換的に使用することができますが、何かが '文字列'であるかどうかをチェックするために 'instanceof'を使うことはできません。 – Halcyon

+1

' [] 'は配列リテラルではありません。 ''は文字列リテラルですか? – FishBasketGordo

+0

@FishBasketGordo配列には、あらゆる種類のプリミティブとオブジェクトを含めることができます。 –

11

''は、オブジェクト、原始的ではないためにです。

JavaScriptのプリミティブの中には、オブジェクトラッパーを持つものがあります。これらは、newの組み込みコンストラクターを使用してラッパーのインスタンスを作成すると作成されます。

通常、newを除外すると、関数がプリミティブに強制されることが多いため、newが必要です。

typeof new String(''); // "object" 
typeof String('');  // "string" 
typeof '';    // "string" 

オブジェクトのラッパーを持っているプリミティブはstringnumberbooleanです。

nullおよびundefinedのプリミティブはありません。

+0

'[]'のプリミティブ(つまりラッパー以外のオブジェクト)は何ですか? – Randomblue

+2

Randomblue:1つではありません。配列は常にオブジェクトです。 –

+0

@Randomblueは存在しません。なぜプリミティブがあるのでしょうか? – Raynos

3

''は何のインスタンスでもありません。それはプリミティブ型で、5.5またはtrueとほぼ同じように動作します。文字列プリミティブとStringオブジェクトには違いがあります。参照:new String()new Number()またはnew Boolean()で作成

new String('') instanceof String; // true 

ものは、プリミティブ型の周りのオブジェクトラッパーである、と彼らは同じではありませんね。

、文字列などをチェックする代わりにtypeofを使用するには:

typeof '' === 'string'; // true 

両方をチェックするには、この使用:のためObject.prototype.toString.callを使用する理由のカップルがあります

Object.prototype.toString.call('') === '[object String]'; // true 
Object.prototype.toString.call(new String('')) === '[object String]'; // true 

を配列、文字列、数値の一般的なコードブール値。それらは次のとおりです。

  1. 文字列、数値、ブール値の場合、人々はプリミティブ型の代わりにラッパーオブジェクトのインスタンスを渡すことがあります。それらは通常、暗黙的に(暗黙的にvalueOf()を使用して)機能します。したがって、ライブラリコードを記述する場合はそれらを受け入れるべきです。
  2. 配列の場合、別のウィンドウ(たとえば)から配列を受け取った場合、instanceof Arrayを使用すると、falseが返されます。 Object.prototype.toString.callメソッドは、すべての目的に使用できます。

これは、jQueryと他の大規模な一般的なライブラリの機能です。

1

私はいくつかの掘り下げをしており、それはコンパイラの最適化であるstring interningと関係があると思います。

さて、いくつかの落ち着きの準備ができましたか? :D

"abc" == "abc"; // true 
"abc" === "abc"; // true 

私はこれが原因で偶然にも(右「文字列」を取得するためのイェーイ)概念的に、多くの意味を作る「インターン文字列」の真であると仮定します。

new String("abc") == new String("abc"); // false 
new String("abc") === new String("abc"); // false 

あなたはStringがオブジェクトであり、オブジェクトが同様の内部状態を持つオブジェクトに等しいだけで、それ自体に等しいと仮定していない場合、これは理にかなっています。 Javaのように(あるいはそれはどうにか使われていた)。

そして今、キッカーのために:

(new String("abc")).substr(0,3) === (new String("abc")).substr(0,3); // true! 

だから、明らかJavaScriptインタープリタは常にStringオブジェクトを使用する上でのインターンの文字列を好むでしょう。

次に、Stringオブジェクトの使用は何ですか?どうやら、友人とうまくやっていないようです。

+0

最初の '' abc」===「abc」 'は、文字列インターナショナルのためではありません。厳密な平等は、プリミティブ型に期待されるように機能します。 '==='はオブジェクトの "reference-equals"だけです。 – Ryan

+0

文字列 'type'は、プロトタイプを拡張し、' Objects'のような文字列を作成できるようにするためだけにあります。つまり、オブジェクト(Cのポインタに似ています)は 'same pointer'の場合にのみ' === 'になります – Adaptabi