John
John

Reputation: 13759

JavaScript dash throws off ReferenceError

The following JavaScript...

if (eval('typeof admin_post_css_theme_dark-moon)=='function')) {/**/}

...triggers the following error message...

Error: ReferenceError: moon is not defined

The only thing I can really differentiate in this situation is that other themes don't have a dash in their names...

if (eval('typeof admin_post_css_theme_silver)=='function')) {/**/}

...doesn't trigger any errors.

So how is the dash between 'dark' and 'moon' triggering this error?


Edit: I wanted to take a moment and recommend that others who encounter this should adapt camelCase or something similar. In general I use a 'name' and a 'base' myself. The 'base' is the URL-friendly version of something that the 'name' includes URL unfriendly characters. In example 'My Example' and 'my-example' or 'my_example'.

http://en.wikipedia.org/wiki/CamelCase

Upvotes: 1

Views: 748

Answers (3)

OJay
OJay

Reputation: 4921

Primarily because '-' is not a valid identifier in javascript, its the minus sign. Your eval in essence is trying to get the typeof the expression admin_post_css_theme_dark minus moon. Valid identifiers (i.e. variable, function or object names) in javascript are [A-Za-z0-9_$] but cannot start with a number (note this is a regex, and the hyphens in this context mean range i.e. a to z, just in case it was unclear)

My evolution to the question would be how would you have expected admin_post_css_theme_dark-moon to be defined, as you are expected it to be somehow/where in code, then in turn to test if it is a function.

As it would be absolutely impossible to do this

var admin_post_css_theme_dark-moon = function(){...};

//or

admin_post_css_theme_dark-moon = function(){...};

however it is possible to do this.

window['admin_post_css_theme_dark-moon'] = function(){...};

or preferably use your own object

var Themes = {};
Themes['admin_post_css_theme_dark-moon'] = function(){...};

//or

var Themes = {
    'admin_post_css_theme_dark-moon' : function(){...};
}

As object properties if referenced by string index (i.e. between [] as a string) are not bound by the identifier rules.

then of course your eval would have to change also

something like

if (eval("typeof window['admin_post_css_theme_dark-moon']")=='function')) {/**/}

//or

if (eval("typeof Themes['admin_post_css_theme_dark-moon']")=='function')) {/**/}

NOTE the use of alternating " and ' so you don't have to escape

Upvotes: 5

John
John

Reputation: 13759

I changed...

eval('typeof '+my_object)=='function')

...to...

eval('typeof \''+my_object+'\'')=='function')

I didn't have the chance to edit this in so the question could be more concise. For those looking at just this answer check out the other answers from OJay and sabof as they are wholly relevant.

Upvotes: -1

sabof
sabof

Reputation: 8192

JavaScript variable names can't contain dashes, object properties however can. For instance, something like this would work:

var themes = {
  'admin_post_css_theme_dark-moon': function () {},
  'admin_post_css_theme_silver': function () {}
};

if (typeof themes['admin_post_css_theme_dark-moon'] === 'function') {
  /**/
}

Upvotes: 6

Related Questions