0

i read instanceof answer,but i have a question When i code

["a","b"] instanceof Array

why it reutrns true as the same as

new Array("a","b") instanceof Array

while

"a" instanceof String

returns false not as the same as

new String("ab") instanceof String 

? very appreciate for your answers and help!

Community
  • 1
  • 1
王奕然
  • 3,891
  • 6
  • 41
  • 62

3 Answers3

2

For strings, you have both

  • primitive strings (the ones you manipulate most of the times, and that you get from literals)
  • and instances of the String class.

And they're not the same.

Here's what the MDN says on the distinction between both.

Another way to see the difference, which the MDN doesn't point, is that you can add properties on objects :

var a = "a";
a.b = 3; // doesn't add the property to a but to a wrapped copy
console.log(a.b);  // logs undefined
a = new String("a");
a.b = 3;
console.log(a.b);  // logs 3

(remember that most of the times, you should use primitive strings)

For arrays, you only have arrays, there is nothing like a primitive array.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
0

In your case

"a"   

is not a String Object, it is a String literal or as it is called a "primitive". So JS is not betraying you, claiming, that "a" is not an instance of String. CF MDN on String

Thomas Junk
  • 5,588
  • 2
  • 30
  • 43
  • 2
    A string literal and a string primitive are not the same. A literal is a *syntactic* construct. It tells the lexer that the sequence of characters is supposed to be a string. A string primitive is data type which exists at *run time* (not parsing time). It's true though that a string *literal* always results in a string *primitive*. – Felix Kling Aug 07 '13 at 10:11
  • Thanks for making that clear. In Javascript I thought it would could be used interchangeably. – Thomas Junk Aug 07 '13 at 10:20
  • It probably is often used interchangeably, but that doesn't mean it's correct. Plus I'm a bit picky ;) – Felix Kling Aug 07 '13 at 10:21
0

The instanceof check is defined as:

When the [[HasInstance]] internal method of F is called with value V, the following steps are taken:

  1. If V is not an object, return false.
  2. Let O be the result of calling the [[Get]] internal method of F with property name "prototype".
  3. If Type(O) is not Object, throw a TypeError exception.
  4. Repeat
    1. Let V be the value of the [[Prototype]] internal property of V.
    2. If V is null, return false.
    3. If O and V refer to the same object, return true.

So string fails the very first step because string is not an object. Also note that new String doesn't return a string but an object constructed from a constructor called String. This is one example how Java and Javascript is completely different.

Here is also code for a custom instanceOf, make it work however you like then:

function instanceOf(F, V) {
    if( typeof F !== "function" ) {
        throw new Error( "F must be a constructor" );
    }
    if( Object(V) !== V ) {
        return false; //not an object
    }
    var O = F.prototype;
    if( Object(O) !== O ) {
        throw new Error( ".prototype must be an object" );
    }
    while( true ) {
        V = Object.getPrototypeOf(V);
        if( V == null ) {
            return false;
        }
        if( V === O ) {
            return true;
        }
    }
}
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • thanks,i understand the first item,but what is O and [[Get]] internal method?Are they javascript internal implements?the custom instanceof(F,V),F parameter represent what?how to use this program? – 王奕然 Aug 08 '13 at 06:17
  • @user2245634 they are technical explanations how something should work. To use [[Get]] Operation of `F` with property name `"prototype"`, you just do `F.prototype`. `[[Get]]` Operation is also explained separately in the specification. – Esailija Aug 08 '13 at 06:52