i am processing an object in JavaScript that has been returned from an API that may contain variable names that are not valid JavaScript variable names. (these names are valid in the naming convention of the system of the API i am using)
in one case, the name starts with a number, e.g. '5story'
what is the best way to convert this name to a valid JavaScript variable name?
(i am familiar with the form of legal JavaScript names. a useful answer to this question would be a (hopefully simple) algorithm e.g. prefix a $ to the name and then strip it when returning the form to the API)
(i note that it would be preferable if the JavaScript API did not create invalid names)
Note that I'm not sure if you're asking about html identifier names (you mention "form") or Javascript variable identifiers, but how about stripping any character that is not a word character (A-Z, a-z, 0-9, _) and prepending with an underscore?
var v = ' .-*&*$*$W 5 foo Bar';
v = '_' + v.replace(/\W/g, '');
v; // _W5fooBar
The .replace() will strip characters that are not legal in variable identifiers.
You could prepend with the $ symbol instead of underscore for a legal variable name too.
You could creat a wrapper object that also contained a back reference to the original name.
function MyApiClient()
{
var _self = this;
this.RegisterWrapper = function(strName, objValue, explicitName)
{
var newName = (explicitName != null) ? explicitName : '_' + strName.replace(/\W/g, '');
_self[newName] = {ApiName : strName, Value : objValue};
return _self[newName];
}
}
//implementation
var client = new MyApiClient();
client.RegisterWrapper('5story', [0,1,2,3,4,5]);
console.log(client._5story.Value); //output: Array() [0,1,2,3,4,5];
//or
var o = client.RegisterWrapper('5story', {a:'b'}, '_myName');
console.log(o.Value); //outpus Object a: 'b'
console.log(client._myName.Value); //outpus Object a: 'b'
This extends a couple additional benefits
Scope: when creating the new objects they will be encapsulated and not globals
Reference: if you have reference to this object - you can use it to hit your API (because it will contain the old name)
Flexibility: you can either register the wrappers dynamically through a loop as you parse a string returned from the api or explicitely like above.
Do you have any more information about the actual api?
Related
I am looking for information on the difference between acceptable variable names in JavaScript, when they are key names in an object versus when the variables are referenced declaratively.
For example:
in an object, I can do this:
var obj = {
'##A': 1,
'#B': 2,
'C*': 3
};
however, we cannot reference those variables in the code, as this will be some form of syntax error
of course, we cannot do this:
obj.##A++; //syntax error
obj.#B++; //syntax error
obj.C*++; //syntax error
and we definitely cannot do this either:
var ##A = 1; //syntax error
var #B = 2; //syntax error
var C* = 3; //syntax error
I believe the primary difference is that the key of object can take any value of a JS Symbol. Whereas a variable name cannot take any value of Symbol.
So this is a two part question:
How is this disparity described in JavaScript? What was the motivation to have the disparity between Symbol's being valid key names but not valid variable names?
Is there a publicly available regex that can validate a JS variable name? I want to run this regex against keys of a particular object. The reason is that users of a library that I am writing will define variable names with the keys from an object, and they could easily use Symbol characters that would be invalid JS variable names.
To be more specific, this is for a dependency injection facility.
The end-user defines dependencies like so:
const deps = {
'request': function(){
return require('request'); //useless, but as a simple example
},
'users': function(){ //no problems here
return db.users.find({});
},
'users-older-than-13': function(){ //invalid because of "-" chars
return db.users.find({age: {gt: 13}});
}
};
I am working through the exercises in the book Object-Oriented JavaScript by Stoyan Stefanov. The exercise is asking me to create a function constructor for a String object. None of the built-in String properties or methods can be used. I am trying to recreate returning a character at a certain index of a string. So the following code is the part of the exercise I am having difficulty getting to work:
var s = new MyString('hello');
s[0];
I cannot figure out how to have my function constructor return the character at the index specified. I should be able to display to the screen the character 'h'. I was able to specifically target certain indexes but that would not be usable as there could be any number of characters in the string passed into the function constructor. Here is the code for that, this return value is for the constructor itself:
return {
'0': this.string[0]; // Is this code using built-in String object properties or methods?
}
Okay thanks if you can point me in the right direction.
A simple way to achieve this is to not make it act like a real string, but only deal with the letters that do exist by running over the input string as an array using forEach:
var MyString = function(content) {
var thisObject = this;
var letters = content.split('');
letters.forEach(function(letter, position) {
thisObject[position] = letter;
});
};
JS objects are all dynamic property/value maps, so you can set a binding that is effectively this[0] = 't'; this[1] = 'h'; this[2] = 'e' and have something that works.
Does this make sense to do? Not... really? I don't quite see what this exercise teaches you if it's telling you that your code should allow for yourstring[somenumber], but this would be one way to do it.
I have the following function (which I didn't write) to extract a URL parameter value:
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [, ""])[1].replace(/\+/g, '%20')) || null
}
I have virtually no experience with regular expressions. This code currently does a case sensitive search for the parameter name. I'd like to have RegExp do a case insensitive search for the name of the parameter. Could someone show me how I might change this to accomplish that?
Add i flag for regexp(more info):
new RegExp('your regexp', 'i')
Here's something that I've been using that may help, as I need to do something very similar to pull down a substring of the current page's URL to then pass into a variable to be used in several of my functions.
Here's the generic format of my URLs:
file:///Users/myname/folder/teamname.html
And here's what how I'm parsing them:
function parseURL() {
var match = window.location.href.match(/(\w+).html$/);
if (match) {
return match[1];
}
return null;
}
This will do this:
1) Check the URL for the current page
2) Parse the URL into two different fragments of an array: "teamname" and "html"
3) I then return match[1] which is "teamname"
How I'm using it:
From there, I declare a variable for the parseURL function like this:
var teamSched = parseURL();
So now, I can make dynamic calls for any page with the same URL syntax I've outlined above to have specific code executed with the page-specific variable from parseURL(). Then, I use that variable to generate unique datasets from objects in my code who's key match the "team name" variable created by parseURL().
Someone definitely correct me if I'm wrong, but case sensitivity shouldn't be a factor here, as long as the value you're pulling from your URL via parseURL matched the variable, object key, etc. you're trying to access.
I hope that helps!
This question already has answers here:
JavaScript property access: dot notation vs. brackets?
(17 answers)
Closed 9 years ago.
What is the difference, if any, between these two assignments:
var foo = {};
foo['bar'] = "some value";
foo.baz = "some other value";
console.log(foo.bar)
=> "some value"
console.log(foo.baz)
=> "some other value"
Are they synonymous? I've noticed you can add keys with the [] syntax that are not valid property names.
foo['a space'] = "does not work";
console.log(foo.a space);
=> SyntaxError: Unexpected identifier
My reason for asking is that I've cooked up a little JS library for pseudo namespacing. It is written on the assumption that the above assignments are identical (ignoring the superset allowed when using [] syntax)
foo["bar"] is equivalent to foo.bar, although foo.bar is easier to read in my opinion. As you already noticed the former syntax (foo["bar"]) allows you to use property names that are not valid identifiers. It also allows you to use dynamic property names:
var name = "bar";
foo[name] = 1;
console.log(foo["bar"]);
will output 1.
When you use ., the property name is a literal identifier. When you use this in a program, you have to hard-code the property name.
When you use [], the property name is an expression that is evaluated. It's not normally used with simple strings in quotes, because that's what . notation is for. But it's useful when you need to calculate the property, e.g.
console.log(foo["item"+i]);
This latter notation is also the only way to access properties that aren't identifiers. You can use any string as the property name this way.
They are absolutely equivalents except that you can more possibilities with [] syntax for example
var bar = 'text';
foo[bar] = 'baz';
The only difference is you can use variables in the second example however it's is always better to use dot notation like this
someObject.hello = ' hello john';
And the only time i use the other way is if i need to use a variable like this
var msg = 'goodbye';
someObject[msg] = 'goodbye john';
This would be the result
// someObject.hello => 'hello john'
// someObject.goodbye => 'goodbye john'
so use dot notation like obj.some and use obj[myVar] for variables
So the difference is you can use variables in the 2nd example
also if i done this
var myVar = 'test';
someObj.myVar = ' Hello Test ';
then this would be the result
// someObj.test => doesnt work - undefined
// someObj.myVar => ' Hello Test '
They are equivalent, but you cannot use the dot notation when the attribute-name contains a space (or other non-alphanumeric characters):
foo.a space // doesn't work
foo['a space'] // does
I have a javascript objects var flower_1; var flower_2;
My question is if I have another variable for example a String var Name;
And lets say for example: Name = "flower_1";
How can I change the Name variable into an object "flower_1"
If I understand your question correctly, you have something like this:
function foo() {
var flower_1 = { /* ... */ };
var flower_2 = { /* ... */ };
var name = "flower_1";
var target = /* code here to get the correct object based on `name` */;
}
You can do that, but it should be avoided if at all possible:
var target = eval(name);
eval is a very big, and easily abused tool which should be, and can be, avoided. I've never had to use it in production code in several years of JavaScript development. Also note that eval is disallowed in the new "strict" mode of the language (one of many improvements strict mode brings).
In this particular case, it's pretty easy to avoid:
function foo() {
var objects = {
flower_1: { /* ... */ },
flower_2: { /* ... */ }
};
var name = "flower_1";
var target = objects[name];
}
Now, flower_1 and flower_2 are properties of an object, and you can use bracketed notation ([]) with a string name to access those properties. This is because in JavaScript objects, you can either access a property using dotted notation and a literal (e.g., obj.foo), or using bracketed notation and a string (e.g., obj["foo"]). In the second case, the string doesn't have to be a string literal, it can be the result of an expression, including (as in this case) retrieving the string from a variable.
Here's a live example of both techniques.
Note that if your var statements are globals, then those vars become properties of the global object, which on web browsers is window, so if they're globals you could access them via window[name] for exactly the same reason objects[name] works. But it's best practice to avoid global variables (entirely if you can, or exposing just one with a good unique name that then contains all of your public stuff if necessary — e.g., if external code needs to access your stuff).
You can use the eval() function:
var flower_1 = "abc";
var name = "flower_1";
var x = eval(name); // = "abc"
It's worth noting though that use of the eval() function is not best practise, and should be avoided at all costs.
A better (and much more recommended) solution would be to use an associative array:
var name = "flower_1";
var arr = new Array();
arr["flower_1"] = "abc";
var x = arr[name]; // = "abc"