What is the difference between string primitives and String objects in JavaScript?

前端 未结 12 1524
孤街浪徒
孤街浪徒 2020-11-22 07:58

Taken from MDN

String literals (denoted by double or single quotes) and strings returned from String calls in a non-constructor context (i.e., witho

相关标签:
12条回答
  • 2020-11-22 08:27

    I can see that this question has been resolved long ago, there is another subtle distinction between string literals and string objects, as nobody seems to have touched on it, I thought I'd just write it for completeness.

    Basically another distinction between the two is when using eval. eval('1 + 1') gives 2, whereas eval(new String('1 + 1')) gives '1 + 1', so if certain block of code can be executed both 'normally' or with eval, it could lead to weird results

    0 讨论(0)
  • 2020-11-22 08:27

    The code is optimized before running by the javascript engine. In general, micro benchmarks can be misleading because compilers and interpreters rearrange, modify, remove and perform other tricks on parts of your code to make it run faster. In other words, the written code tells what is the goal but the compiler and/or runtime will decide how to achieve that goal.

    Block 1 is faster mainly because of: var s = '0123456789'; is always faster than var s = new String('0123456789'); because of the overhead of object creation.

    The loop portion is not the one causing the slowdown because the chartAt() can be inlined by the interpreter. Try removing the loop and rerun the test, you will see the speed ratio will be the same as if the loop were not removed. In other words, for these tests, the loop blocks at execution time have exactly the same bytecode/machine code.

    For these types of micro benchmarks, looking at the bytecode or machine code wil provide a clearer picture.

    0 讨论(0)
  • 2020-11-22 08:29

    String Literal:

    String literals are immutable, which means, once they are created, their state can't be changed, which also makes them thread safe.

    var a = 's';
    var b = 's';
    

    a==b result will be 'true' both string refer's same object.

    String Object:

    Here, two different objects are created, and they have different references:

    var a = new String("s");
    var b = new String("s");
    

    a==b result will be false, because they have different references.

    0 讨论(0)
  • 2020-11-22 08:32

    In Javascript, primitive data types such is string is a non-composite building block. This means that they are just values, nothing more: let a = "string value"; By default there is no built-in methods like toUpperCase, toLowerCase etc...

    But, if you try to write:

    console.log( a.toUpperCase() ); or console.log( a.toLowerCase() );
    

    This will not throw any error, instead they will work as they should.

    What happened ? Well, when you try to access a property of a string a Javascript coerces string to an object by new String(a); known as wrapper object.

    This process is linked to concept called function constructors in Javascript, where functions are used to create new objects.

    When you type new String('String value'); here String is function constructor, which takes an argument and creates an empty object inside the function scope, this empty object is assigned to this and in this case, String supplies all those known built in functions we mentioned before. and as soon as operation is completed, for example do uppercase operation, wrapper object is discarded.

    To prove that, let's do this:

    let justString = 'Hello From String Value';
    justString.addNewProperty = 'Added New Property';
    console.log( justString );
    

    Here output will be undefined. Why ? In this case Javascript creates wrapper String object, sets new property addNewProperty and discards the wrapper object immediately. this is why you get undefined. Pseudo code would be look like this:

    let justString = 'Hello From String Value';
    let wrapperObject = new String( justString );
    wrapperObject.addNewProperty = 'Added New Property'; //Do operation and discard
    
    0 讨论(0)
  • 2020-11-22 08:35

    When you declare:

    var s = '0123456789';
    

    you create a string primitive. That string primitive has methods that let you call methods on it without converting the primitive to a first class object. So your supposition that this would be slower because the string has to be converted to an object is not correct. It does not have to be converted to an object. The primitive itself can invoke the methods.

    Converting it to an full-blown object (which allows you to add new properties to it) is an extra step and does not make the string oeprations faster (in fact your test shows that it makes them slower).

    0 讨论(0)
  • 2020-11-22 08:36

    If you use new, you're explicitly stating that you want to create an instance of an Object. Therefore, new String is producing an Object wrapping the String primitive, which means any action on it involves an extra layer of work.

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

    As they are of different types, your JavaScript interpreter may also optimise them differently, as mentioned in comments.

    0 讨论(0)
提交回复
热议问题