javascript - String to real Object - javascript

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"

Related

Storing a pointer in javascript

Is it possible to keep an object reference without using an holder object in javascript?
Currently when an object gets overridden I sometimes lose the reference to the "current" object state illustrated in the snippet below;
Is there a way to put a "pointer" in an array or not?
EDIT
To the questions asked:
What I have in the objects I have are references to form fields. Some of these are text fields, some of them are textareas, some of them checkboxes.
I wish to keep a map next to the direct referene of what type they are.
basicaly it would be
obj {
this.text1 = createTextField();
this.text1.datepicker();
this.text2 = createTextField();
this.area1 = createArea();
this.check = createCheck();
this.datefields = [this.text1];
this.checkboxes = [this.check];
}
So I can use the datefields/checkboxes array as a checkpoint to validate against which type a field is/should behave.
Currently I use
function datefields() { return [this.text1]; };
But I'd like to know if there's a better way to do this than to intantiate a new array when I need to check it.
I know there is a way with observers to mimic pointer behaviour, and i've fiddled with those and have some good results with that, i'm just curious if there are other ways i'm not aware of.
function myObject() {
this.myvalue = null;
this.arr = [this.myvalue];
}
myObject.prototype.alter = function() {
this.myvalue = "hello";
}
var x = new myObject();
var elem = document.getElementById('results');
function log(message) {
elem.appendChild(document.createTextNode(message));
elem.appendChild(document.createElement('br'));
}
log("x.myvalue = "+x.myvalue);
log("x.arr[0] = "+x.arr[0]);
log("calling alter");
x.alter();
log("x.myvalue = "+x.myvalue);
log("x.arr[0] = "+x.arr[0]);
<div id="results"></div>
Simple answer: Only objects (including all subtypes) are passed by reference in JS. All other simple values are copied.
For a bit more detail I would recommend reading You Don't Know JS: Types & Grammer but specifically the section Value vs Reference in Chapter 2:
In JavaScript, there are no pointers, and references work a bit differently. You cannot have a reference from one JS variable to another variable. That's just not possible.
Quoting further on:
Simple values (aka scalar primitives) are always assigned/passed by value-copy: null, undefined, string, number, boolean, and ES6's symbol.
Compound values -- objects (including arrays, and all boxed object wrappers -- see Chapter 3) and functions -- always create a copy of the reference on assignment or passing.
There are plenty of examples included to show these points. I would highly recommend reading through to get a better understanding of how values/references work in JS.
There is no pointers in Javascript, though you could cheat a little using a wrapper object. Here is a minimal implementation of such an object:
var Wrapper = function (value) {
this.value = value;
};
Wrapper.prototype.valueOf = function () {
return this.value;
};
Then you may use it in place of the original value:
function myObject() {
this.myvalue = new Wrapper(null); // wrapper
this.arr = [this.myvalue];
}
myObject.prototype.alter = function() {
this.myvalue.value = "hello"; // notice the ".value"
}
The rest of your code needs no tweaks.

Declarating a variables with for operator in Javascript

I got an 2x10 array and I need set a variable to any member of that array. Make it by hands its not cool, so Im trying to declarate by for operator:
allImages=[
[
'img1-1','img1-2', 'img1-3', 'img1-4', 'img1-5'
],[
'img2-1','img2-2', 'img2-3', 'img2-4', 'img2-5'
]
];
for(i=0;i<1;i++){
console.log(i + ' part ------------------------');
for(j=0;j<5;j++){
x+(i+'-'+j) = allImages[i][j];
console.log((x+(i+'-'+j)) + '-> item');
}
}
But looks like I make a primitive error:
Invalid left-hand side in assignment
Anyway, I cant figure out how to solve this. Can anyone say how to declarate a lot of variables with custom keys throw for operator or with another method?
----- My solution by(https://stackoverflow.com/users/1230836/elias-van-ootegem):
var statImg = {};
var blurImg ={};
for (var i = 0; i < 13; i++) {
var keyName = 'img'+i;
var valOfKey = 'img/'+i+'.png'
statImg[keyName] = valOfKey;
blurImg[keyName] = valOfKey;
};
You'll have to either create an object, and use the left-hand trickery you're trying to generate property names, or you'll have to fall back to the global object (which I hope you don't):
var names = {};//create object
//-> in loop:
names[ x+(i+'-'+j)] = allImages[i][j];
To be complete, but again: don't actually go and do this, you could replace names with window. In which case, you'll be polluting the global scope.
Perhaps you might want to check the values (like x, i and j) for values that make it "difficult" to access the properties, like %, or indeed the dash you're concatenating in your example:
var anObj = {};
anObj['my-property'] = 'this is valid';
console.log(anObj.my-property);//ReferenceError: property is not defined
That is because the dash, or decrement operator isn't seen as part of the property. Eitherway, using separate variables is, in your case, not the best way to go. Programming languages support arrays and objects because of this very reason: grouping related data, making them easy to access through a single variable.
If needs must, just use an object, if not, construct an array you sort using array.sort(function(){});
check MDN on how to acchieve this, if you're stuck down the way, let us know....

JavaScript official keywords shortcuts

I've seen something similar to this code in the Google API JavaScript, I mean the r=Array part. Here is an example of what they have done:
var r = Array;
var t = new r('sdsd' , 'sdsd');
alert(t[0]);
Few questions about this:
Is it legal to write like this and won't cause any problems?
I can do something similar with other keywords like ´For´ loop or with the ´this´ keyword?
Can I have article about this JavaScript official keyword shortcuts etc..?
Thank you in advance.
That works because Array is an object. You can do that with any object. For example, the Date object:
var d = Date;
console.log((new d()).getTime()); //Prints time
You cannot do that for keywords such as for or while because they are language constructs that will be recognised by the interpreter.
You can do it with this:
document.getElementById("b").onclick = function() {
var x = this; //this holds a reference to the DOM element that was clicked
x.value = "Clicked!";
}
In fact, that can be very useful sometimes (to keep a reference to this so you can access it from an anonymous inner function for example). This also works because, to put it simply, this will be a reference to an object.
Yes
for - no. this - yes.
You can store references to any JavaScript object in a variable. String, Array, Object, etc. are JavaScript objects that are built-in to the language. for, if, while, etc. are are JavaScript statements, and cannot be stored or referenced any other way.
You can do it the other way around as well (and really mess yourself up in the process):
Array = 0;
var myArray = new Array("a", "b", "c"); // throws error
This is easily undone like this:
Array = [].constructor;
Edit: Being able to assign the value of this to a variable is essential when nesting functions that will execute in a different scope:
function Widget() {
var that = this;
this.IsThis = function() {
return isThis();
};
function isThis() {
return that == this;
}
}
new Widget().IsThis(); // false!
Maybe not the best example, but illustrates losing scope.
You cannot reassign the value of this:
function doSomething() {
this = 0; // throws error
}

How to declare string constants in JavaScript? [duplicate]

This question already has answers here:
Are there constants in JavaScript?
(33 answers)
Closed 6 years ago.
I want to declare string constants in JavaScript.
Is there is a way to do that?
Many browsers' implementations (and Node) have constants, used with const.
const SOME_VALUE = "Your string";
This const means that you can't reassign it to any other value.
Check the compatibility notes to see if your targeted browsers are supported.
Alternatively, you could also modify the first example, using defineProperty() or its friends and make the writable property false. This will mean the variable's contents can not be changed, like a constant.
Are you using JQuery? Do you want to use the constants in multiple javascript files? Then read on. (This is my answer for a related JQuery question)
There is a handy jQuery method called 'getScript'. Make sure you use the same relative path that you would if accessing the file from your html/jsp/etc files (i.e. the path is NOT relative to where you place the getScript method, but instead relative to your domain path). For example, for an app at localhost:8080/myDomain:
$(document).ready(function() {
$.getScript('/myDomain/myScriptsDir/constants.js');
...
then, if you have this in a file called constants.js:
var jsEnum = { //not really an enum, just an object that serves a similar purpose
FOO : "foofoo",
BAR : "barbar",
}
You can now print out 'foofoo' with
jsEnum.FOO
There's no constants in JavaScript, but to declare a literal all you have to do is:
var myString = "Hello World";
I'm not sure what you mean by store them in a resource file; that's not a JavaScript concept.
Of course, this wasn't an option when the OP submitted the question, but ECMAScript 6 now also allows for constants by way of the "const" keyword:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
You can see ECMAScript 6 adoption here.
Standard freeze function of built-in Object can be used to freeze an object containing constants.
var obj = {
constant_1 : 'value_1'
};
Object.freeze(obj);
obj.constant_1 = 'value_2'; //Silently does nothing
obj.constant_2 = 'value_3'; //Silently does nothing
In strict mode, setting values on immutable object throws TypeError. For more details, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
Well, you can do it like so:
(function() {
var localByaka;
Object.defineProperty(window, 'Byaka', {
get: function() {
return localByaka;
},
set: function(val) {
localByaka = window.Byaka || val;
}
});
}());
window.Byaka = "foo"; //set constant
window.Byaka = "bar"; // try resetting it for shits and giggles
window.Byaka; // will allways return foo!
If you do this as above in global scope this will be a true constant, because you cannot overwrite the window object.
I've created a library to create constants and immutable objects in javascript. Its still version 0.2 but it does the trick nicely. http://beckafly.github.io/insulatejs
Starting ECMAScript 2015 (a.k.a ES6), you can use const
const constantString = 'Hello';
But not all browsers/servers support this yet. In order to support this, use a polyfill library like Babel.
So many ways to skin this cat. You can do this in a closure. This code will give you a read-only , namespaced way to have constants. Just declare them in the Public area.
//Namespaced Constants
var MyAppName;
//MyAppName Namespace
(function (MyAppName) {
//MyAppName.Constants Namespace
(function (Constants) {
//Private
function createConstant(name, val) {
Object.defineProperty(MyAppName.Constants, name, {
value: val,
writable: false
});
}
//Public
Constants.FOO = createConstant("FOO", 1);
Constants.FOO2 = createConstant("FOO2", 1);
MyAppName.Constants = Constants;
})(MyAppName.Constants || (MyAppName.Constants = {}));
})(MyAppName || (MyAppName = {}));
Usage:
console.log(MyAppName.Constants.FOO); //prints 1
MyAppName.Constants.FOO = 2;
console.log(MyAppName.Constants.FOO); //does not change - still prints 1
You can use freeze method of Object to create a constant. For example:
var configObj ={timeOut :36000};
Object.freeze(configObj);
In this way you can not alter the configObj.
Use global namespace or global object like Constants.
var Constants = {};
And using defineObject write function which will add all properties to that object and assign value to it.
function createConstant (prop, value) {
Object.defineProperty(Constants , prop, {
value: value,
writable: false
});
};
Just declare variable outside of scope of any js function. Such variables will be global.

javascript - updating global object variables via a function

Weird problem here, I'm trying to use a global function to update my settings object, example:
var Settings = new Object;
Settings.savepos = 'true';
function UpdateSetting(obj,value){
eval("Settings.obj = value");
alert(Settings.savepos);
}
The obj is the key of the object, meaning if I call the function with
UpdateSetting('savepos','false')
the alert will always just give me true, how do I convert that eval or any alternative so it will update settings object's key with the value?
You are setting Settings.obj, not setting.savepos.
Try this instead:
function UpdateSetting(obj,value){
Settings[obj] = value;
alert(Settings.savepos);
};
You are always changing the "obj" key of the object to equal value, which is likely to be undefined (or, at least, not defined to what you want) in the context eval() executes it in. So, you have two options. First, you can keep using eval() (although i don't recommend it because it's more pain than necessary):
var Settings = new Object;
Settings.savepos = 'true';
function UpdateSetting(obj,value){
eval("Settings."+obj+" = '"+value+"'");
alert(Settings.savepos);
}
Or, as numerous other have suggested, you can use the array operator[] to access the property by key:
var Settings = new Object;
Settings.savepos = 'true';
function UpdateSetting(obj,value){
Settings[obj] = value;
alert(Settings.savepos);
}
you dont need an eval
you're setting .obj, not .savepos (there is no interpolation for the string)
you may be calling it wrong.
I'm not exactly sure why you don't just set the value directly (eg. Settings.savepos=false;).
You can attach the function to that object to do something similar:
var Settings = new Object;
Settings.savepos = true;
Settings.UpdateSetting = function (prop,value){this[prop] = value;}
Settings.UpdateSetting('savepos',false);
You should be able to use array notation on the object. Underneath it's just a keyed hash.
Try:
Settings[obj] = value;
I'd also suggest passing values as they are, i.e. string, int, etc:
UpdateSetting('key_name', false);

Categories