There are no char
s in JavaScript. You can use 1 character strings. If you wanted to use integers to save memory, you'd have to call String.fromCharCode
whenever you needed and that would be creating a String
anyway so I find it hard to believe that you would get any benefits from storing integers.
Here's a test where I use an int to stand for 'a'
and create a longer string using both strings and the int http://jsperf.com/using-ints-as-chars
Setup code
var x = "a";
var y = 97;
Creating from ints (383 ops/sec)
var str = '';
for (var i = 0; i < 100000; i++) {
str += String.fromCharCode(y);
}
Creating from 1 char strings (592 ops/sec) FASTER
var str = '';
for (var i = 0; i < 100000; i++) {
str += x;
}
If you're trying to emulate enums in JS, here's one simple way, using strings so it's easier to debug. The strings are compared using pointers so there's no performance penalty
function Enum(key1, key2, ...) {
for (var i = 0; i < arguments.length;; i++) {
this[arguments[i]] = arguments[i];
}
}
var Planets = new Enum('Earth', 'Mars', 'Venus');
//
if (someValue == Planets.Earth) {
// console.log(Planets.Earth) -> outputs "Earth"
}
Ideally, you can't test the enum against a string, if you have a string and you want to compare with an enum, you'd need to convert it into an enum first (to make sure it's one of the valid strings). The following is a safer enum.
function EnumInstance(value) {
this.getValue = function() { // debug only
return value;
}
}
function Enum(enumValues) {
for (var i = 0; i < arguments.length; i++) {
this[arguments[i]] = new EnumInstance(arguments[i]);
}
}
Enum.prototype.fromString = function(enumValue) {
if ( !this[enumValue] ) {
throw new Error('Invalid enum value: ' + enumValue);
}
return this[enumValue];
};
var Planets = new Enum('Earth', 'Venus', 'Mars');
// This outputs false, you can't compare the strings directly
console.log("Are Planets.Earth and 'Earth' equal?", Planets.Earth == 'Earth');
// This outputs true, first convert into an enum
console.log("Are Planets.Earth and Planets.fromString('Earth') equal?",
Planets.Earth == Planets.fromString('Earth'));
// If you try Planets.fromString('Pluto'), an exception will be thrown
try {
var enumValue = Planets.fromString('Pluto')
} catch(e) {
console.log(e);
}
console.log("Are Planets.Earth and 'Earth' equal?", Planets.Earth == 'Earth');
// This outputs true, first convert into an enum
console.log("Are Planets.Earth an 'Earth' equal?",
Planets.Earth == Planets.fromString('Earth'));
Update
As noted by https://stackoverflow.com/users/1945651/jlrishe, string comparison is not doing using address comparison, like regular Object
s, so equality test is going to scan the string. Therefore, the micro optimization would be to use a number instead of a string if you're going to test equality on the string a lot. Note that if you use the "almost-type-safe" enums I showed above, then the equality check would only be for a pointer. See
http://jsperf.com/string-comparison-versus-number-comparison and Is JavaScript string comparison just as fast as number comparison?