0

I've been looking around and have found that JavaScript doesn't really have a string comparison method to test for equality. I've seen that the accepted method is using the === operator. As someone who's learned a classical language like Java or C++ first this scares me because to me it would behave in ways I don't actually intend it to behave.

So I decided to write my own method to compare strings for equality but it's left me wondering what prototype to augment so that all strings have access to this method. Which leads me to my question; What is a string's prototype that it inherits from?

  • 1
    Don't fear, strings are immutable, this is a good thing. – elclanrs Jan 29 '15 at 00:06
  • 6
    "because to me it would behave in ways I don't actually intend it to behave." - care to explain? – Karoly Horvath Jan 29 '15 at 00:07
  • I am not sure what exactly the question is. Is it about String.prototype (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/prototype) or how prototypes work in general? – Thilo Jan 29 '15 at 00:09
  • @elclanrs: I'll look up what immutable means. I've seen it before but have not read up on them. –  Jan 29 '15 at 00:41
  • 1
    @KarolyHorvath: Thinking that you're comparing to see if two strings have the same content when in fact that's not what gets compared in a classical language when you're using == –  Jan 29 '15 at 00:42
  • @Thilo: I wasn't aware of the existence of String.prototype, thank you for your answer. –  Jan 29 '15 at 00:43
  • @MrZalib: well, I think a better mental picture is that those "classical" languages are the exceptions. in most languages, == does what you expect it to do: string comparison. – Karoly Horvath Jan 29 '15 at 10:06

2 Answers2

1

I don't understand how you want to improve the equality comparison, but ...

it's left me wondering what prototype to augment so that all strings have access to this method.

That would be String.prototype.

All String instances inherit from String.prototype. Changes to the String prototype object are propagated to all String instances.

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • `String.prototype.compare = function(another) { return this.valueOf() === another; }` :-D – zerkms Jan 29 '15 at 00:12
  • 1
    @zerkms: Better use strict mode than `.valueOf()` :-) Or if you do, don't forget to call it on `another` as well. `String.prototype.equals = function eq(other) { "use strict"; return this === other; };` – Bergi Jan 29 '15 at 00:18
  • @Bergi that's curious, wasn't aware of that. Any reference? (cannot google it) – zerkms Jan 29 '15 at 00:33
  • 1
    @zerkms: The `this` binding is only coerced to an object (or even: the global object) in sloppy mode; as per [the spec](http://es5.github.io/#x10.4.3) :-) – Bergi Jan 29 '15 at 00:41
1

In Javascript, strings like numbers are primitive types. (Think int, char, etc in Java.) You can tell that this is true, by running

typeof 'my string';//results in 'string'
'my string' instanceof Object;//results in false!

Because strings are primitive types in javascript, it is safe to use the == and === operators. Just like in Java it is safe to compare integers with ==.

Like Java there are object wrapper types for the primitive types, which cannot be compared using == and ===. (Think Integer, Character, etc in Java.) So while technically you can create a String object by running new String('my string'), it is usually a bad idea because it can break expectations about being able to compare strings.

typeof new String('my string');//results in 'object'
new String('my string') instanceof Object;//results in true
'my string' instanceof String;//results in false

Like Java (at least Java 5 and up), Javascript has autoboxing. This allows strings to be treated as though they have properties and functions. Running 'my string'.toUpperCase() is actually doing something more like new String('my string').toUpperCase().

So to summarise:

  1. strings are primitive types, so you can use the comparison operators
  2. beware of creating string objects that cannot be compared in this way
  3. autoboxing allows us to call functions on primitive types.
Nicholas Daley-Okoye
  • 2,267
  • 1
  • 18
  • 12
  • Do you happen to know if two strings that are equal are stored twice in memory or only one copy of it is kept in memory? I mean like `var x = 'a'; var y = 'a'; `, is the 'a' stored twice in memory or it is in some kind of pool an `x` and `y` are holding references to it? – Rafael Eyng Jan 29 '15 at 00:39
  • 1
    @RafaelEyng: See [Do common JavaScript implementations use string interning?](http://stackoverflow.com/q/5276915/1048572). But you shouldn't care, as you can't do anything about it anyways. – Bergi Jan 29 '15 at 00:44
  • Thank you Nicholas, I think I'll skip on augmenting the prototype then. –  Jan 29 '15 at 00:47
  • But isn't because of the fact that a JavaScript engine uses string interning (just-learnt word) that we can compare two strings with `===` and get `true`? Because is kinda hard to believe that strings are **really** primitive types. – Rafael Eyng Jan 29 '15 at 00:51
  • @RafaelEyng: From the language point of view, strings *are* primitive values and `==` just works. What an engine might do internally to achieve this is quite irrelevant. – Bergi Jan 29 '15 at 01:03
  • Thanks for the discussion. But it is only irrelevant to the high level JavaScript programmer. Is totally relevant for the one who is implementing the engine. So, you see, my question is not pointless. – Rafael Eyng Jan 29 '15 at 01:05