It's great to see that you're using strict mode for strict compliance (which should really be the default), however you shouldn't use strict mode the way you are now. You've probably seen strict mode placed inside of functions, but those functions are IIFEs (Immediately Invoked Function Expressions) - it looks a bit like this.
(function() {
'use strict'
}())
The reasoning behind why we encapsulate 'use strict'
inside of a function is pretty simple: 'use strict'
switches on strict compliance for all scripts in the same execution scope that the directive is executed in that are loaded after the directive.
In English, what that means is if you don't encapsulate the 'use strict'
directive inside of a function, any script loaded after the script that initially uses 'use strict'
will have strict compliance turned on as well. Some scripts (unfortunately) are not written with strict compliance in mind and will promptly throw their toys out of the pram if this happens.
So why do I not recommend putting it in arabicToGreek
? Well, strict mode is a good thing (and should be standard), so it'd be better to just define it once per project. For larger projects that use things like Babel, strict mode is automatically applied; for smaller projects, you should just wrap your entire project in an IIFE that has the 'use strict'
directive to prevent yourself from having to redefine it all of the time.
(function() {
'use strict'
function arabicToGreek(input) {
...
}
}())
Note, if you're using Node, each module is already implicitly wrapped in an IIFE, so you can use 'use strict'
in each file just fine.
You'd need to be an electrician to maintain that many switches! As suggested by Quill, you can use an object instead of a large switch statement, which is what I would do:
const characterMap = {
1: 'α',
2: 'β'
}
function arabicToGreek(code) {
return characterMap[code]
}
Of course, this looks a bit like an array, so that could work too, but given that the index of the character is important here I would prefer to use an object just for clarity.
I don't agree with the idea of using hasOwnProperty
here; if a character doesn't exist in the characterMap
object, then attempting to access that property is just going to return undefined
. JavaScript has another alternative for absent values called null
.
The way I like to see the difference is this: undefined
is a value that hasn't been defined; null
is a value that has been defined as explicitly being absent. As a result, in this instance, I would check to see whether or not the expression characterMap[code]
evaluates undefined
and, if it does, return null
instead.
function arabicToGreek(code) {
const character = characterMap[code]
if(character === undefined) {
return null
}
return character
}
If we abuse the fact that undefined
, null
, 0
and false
all evaluate false
in JavaScript (also known as "falsey"), this can be shortened using the logical OR operator (||
) to look like this:
function arabicToGreek(code) {
return characterMap[code] || null
}
Note that in all examples I've used above I've used const
. const
is a keyword introduced in ES6 that essentially ensures that the identifier can be assigned to once and only once. Attempting to reassign it will cause a runtime error.
If you're running this code in an ES5 browser that doesn't support ES6, you'll run into issues because (ironically), 'use strict'
breaks const
prior to ES6 - in ES5, const
was a reserved keyword that didn't actually do anything - same thing as class
. In ES6 these were both codified into actual concepts in the spec. They should work fine on any reasonably modern browser, though, and in any of the newer versions of Node.
As an alternative to using an Object, you may be interested in the ES6 Map, which is a fairly close analogue to a Dictionary from C# or a Map from Java. Key benefits include Map
not having a prototype
(no need to do hasOwnProperty
), keys can be any value (keys in objects are implicitly converted to a string - or Symbol
), and retrieving the length
of a Map
is actually possible without sacrificing your soul to Zalgo.