I would like to know if, when comparing two (potentially massive) strings, JavaScript internally starts by comparing their length before looping over the characters.
If not, would that mean doing something along the lines of
if (string1.length !== string2.length || string1 !== string2)
// do something if data changed
should lead to a gain of time, right ? (I am assuming the read-only length property of a string is computed when the string is set, and not when asked; Not sure if that's actually the case)
For context, I am dealing with massive strings as I am lazily JSON.stringifying arrays of objects received from some API (comparing the latest element only would probably be better but this question is more out of curiosity than anything, please only mind that the strings I would compare would be humongous ^^)
Relevant references ?
https://javascript.info/comparison
Comparing large strings in JavaScript with a hash
Edit
Thank you #RobG in the comment for linking me to ECMA-262's SameValueNonNumber.
In the step definition, step 5 is
SameValueNonNumber ( x, y )
5.If Type(x) is String, then
If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
And I think that answers the question
Related
I got these 2 examples below -
console.log("a" > "3") // outputs true
console.log("hello" > "3") // outputs true
According to MDN, If both values are strings, they are compared as strings, based on the values of the Unicode code points they contain.
But then they also wrote the following in the next paragraph, Strings are converted based on the values they contain, and are converted as NaN if they do not contain numeric values.
Following this logic, shouldn't both statements be false since no matter what the operator it is, "a" and "hello" are words in strings and they don't have a numerical value, therefore, it should return NaN, and NaN is false; hence, as soon as one of the operands is false, it outputs false?
If I need to adhere to the former statement above, could you please walk me through this logic?
Thanks.
The key phrase from the MDN article is
If both values are strings, […].
Otherwise JavaScript attempts to convert non-numeric types to numeric values
So no, "a", "3" and "hello" are all strings, and when comparing them, they get compared as strings. No conversion to anything occurs.
You are comparing two strings (in quotation marks), not a string to a number. This should answer your question:
"a" > "3" //true
"a" > 3 //false
As you've written,
If both values are strings, they are compared as strings, based on the
values of the Unicode code points they contain
So, on both examples, both values are strings. If you change "3" to 3, the result is:
console.log("a" > 3)
// expected output: false
console.log("hello" > 3)
// expected output: false
That's because, first it's converted as NaN, and then:
If either value is NaN, the operator returns false.
The docs:
If both values are strings, they are compared as strings, based on the values of the Unicode code points they contain.
Otherwise JavaScript attempts to convert non-numeric types to numeric values: ....
Reading the docs, I understand that, if BOTH strings have numerical values (both not NaN), then both are treated as Unicode code points. Otherwise, if BOTH have numerical values, then they're converted.
But anyways, my sugestion for a js beginer: do not get too attached to how the language works for now, and even tho it can compare strings with "greater" and "less than", I dont think there would (or should) be a real life scenario where you would need it.
Also, just for fun, check this pen I made when I first started with js (I was also very confused about comparison and typing xD):
"" == null // this one is fun
Later, after learning more about the language, you'll get why somethings work like they do in js, I also recomending understanding the history of js and the web, it explains a lot of the weird behaviours of the language.
Is there an upper limit to the possible character length of strings in JavaScript, and ES6+ in particular?
Could you do this?
const wowThisIsALongString = `${collectedWorksOfWilliamShakespeare}`
[I'd write the collected works out by hand but am feeling lazy.]
If I understand correctly (and odds are that I don't), a JavaScript string is just a special kind of JavaScript Object, so there's technically no limit?
But maybe things are different in practice?
EDIT / UPDATE: As people have noted, a string primitive isn't an Object. I'd never thought of it as such until I checked the ECMAScript 2015 specs.
4.3.17 String value
primitive value that is a finite ordered sequence of zero or more
16-bit unsigned integer
NOTE A String value is a member of the String type. Each integer value
in the sequence usually represents a single 16-bit unit of UTF-16
text. However, ECMAScript does not place any restrictions or
requirements on the values except that they must be 16-bit unsigned
integers.
4.3.18 String type
set of all possible String values
4.3.19 String object
member of the Object type that is an instance of the standard built-in
String constructor
NOTE A String object is created by using the String constructor in a
new expression, supplying a String value as an argument. The resulting
object has an internal slot whose value is the String value. A String
object can be coerced to a String value by calling the String
constructor as a function (21.1.1.1).
So, when they write that, is the meaning that String objects are objects which contain strings, or ... something else?
Another Update: I think that Ryan has answered this below.
There is a specified length of 253 − 1 in Section 6.1.4:
The String type is the set of all ordered sequences of zero or more 16-bit unsigned integer values (“elements”) up to a maximum length of 253-1 elements.
This is the highest integer with unambiguous representation as a JavaScript number:
> 2**53 === 2**53 - 1
false
> 2**53 === 2**53 + 1
true
Individual engines can have smaller limits. V8, for example, limits its strings to 228 − 14 characters.
Side note: primitive strings aren’t objects, but that doesn’t have much to do with length limits. JavaScript has a “primitive wrapper” misfeature allowing strings, numbers, and booleans to be wrapped by objects, and that’s what the section you linked refers to, but there’s no reason to ever use it.
I am building a BODMAS calculator using JavaScript, and working on some code to iterate through all the terms of the equation to find certain mathematical operators and numbers.
var AddPresent = EquationTerms.search(5);
console.log(AddPresent);
If number five is present in the string EquationTerms, it logs the index/position of the number in the string to the console of my browser. If it is not present, it logs -1. While this does not interfere with my program, I am curious: Why does it log -1, and not undefined, or null?
I have searched online, but haven't found an answer which explains the reason. I would be grateful for one which explains this.
This is a pretty common convention, carried over from languages where integers and null were not interchangeable.
A strongly-typed language like C does not let you return null from a function that is declared as returning an integer, so you need to return some integer that denotes "not found". Because there is no way for an element to exist at a negative index, -1 is the most obvious choice.
-1 means "no match found".
The reason it returns -1 instead of "false" is that a needle at the beginning of the string would be at position 0, which is equivalent to false in JS. So returning -1 ensures that you know there is not actually a match.
I'm implementing a sort function and came across the following:
'49' > '5' // false
'49' > '4' // true
new String(49).localeCompare('4') // 1
new String(49).localeCompare('5') // -1
Expected behaviour is obviously that 49 > 4 or 5 should be true. Is there any way to solve this without converting the strings to numbers?
That is actually expected behavior when comparing strings, as described here. The easiest thing for this situation would be to convert the values to numbers for comparison if you want to compare them as numbers.
Thinking outside the box a little, you could first compare the length of the strings before using the > operator. If they are numeric strings, the longer string would have a higher value (assuming you don't have numbers like '0024'). If they are equal in length, the > operator would then work as you expect.
In JavaScript, variables are loosely typed, so the number 5 and the string "5" may both be treated as a number by several operators. However, is there a generic way to find out JavaScripts conversion abilites in at tunrime, or is it just the overloading of operators for several types that make the loose typing possible?
For example, given a variable a and a string containing a type name type_canditate, is there any way to ask JavaScript, if a may convert to type_candidate in a feasable manner, in contrast to the hard typing operators like instanceof? For example, "5" instanceof Number evaluates false, while Math.sin("5") is perfectly feasable. For numbers, one can obviuosly check if parseFloat(some_number) evaluates to NaN, but this is a special case for numbers.
So, is there any generic way of naming types, and check if some variable may convert to a given type in a useful manner?
There are three primitive data types in JavaScript: string, number and boolean.
Anything can be converted to a string or boolean:
All objects convert to true (except null, which becomes false - I only mention it here because typeof null gives object)
All objects have a built-in toString method which is called when converting to a string.
Converting a number to a string is done by giving the string representation of the number (ie. 5 becomes "5")
Numbers convert to boolean true, unless it's 0 which becomes false.
Converting to a number is a little trickier, but technically possible. If it can find a valid number, then it becomes that number. Otherwise, it becomes NaN.
So basically... any type can become any other type through casting in this way. The only time you have anything resembling an "error condition" is NaN.