How can I concatenation parameter name out of 2 strings? [duplicate] - javascript

This question already has answers here:
How to use a string as a variable name in Javascript? [duplicate]
(3 answers)
Closed 9 years ago.
I have the following variable:
var MyVar = "8";
I have 2 strings for example:
var foo = "My";
var bar = "Var";
Now I want to alert MyVar value, meaning to alert "8" and not "MyVar"
alert(foo + bar) // returns "MyVar"

This is a rare case where eval will be needed:
Code
var MyVar = "8",
foo = "My",
bar = "Var";
alert(eval(foo + bar))
Link: http://jsfiddle.net/howderek/wcVNU/

Assuming it's a global variable:
alert(window[foo + bar])
But you're probably better off using objects and properties for that. Object properties can also be accessed with bracket notation:
var obj = {
MyProp : 8
};
var foo = "My";
var bar = "Prop";
alert(obj[foo + bar]);

Without changing the context to much of what you are doing you can use the eval function. However, you have to be very careful with it.
var MyVar = 8;
var foo = "My";
var bar = "Var";
alert(eval(foo + bar));
Depending on what your doing though there are a lot of ways to do this. If you assign MyVar to be part of some context such as this, or window you can simply lookup the value with the key as the variable name.
Window Context
(function () {
window.MyVar = 8;
var foo = "My";
var bar = "Var";
alert(window[foo+bar]);
})();
Function Context
new (function () {
this.MyVar = 8;
var foo = "My";
var bar = "Var";
alert(this[foo+bar]);
})();
Object Context
(function () {
var obj = {}
obj.MyVar = 8;
var foo = "My";
var bar = "Var";
alert(obj[foo+bar]);
})();

Related

How to clone a constructor function so that it constructs a copy of the original type that behaves just like the original, but has its own prototype?

I am trying to clone a constructor function completely, so that it does exactly the same as the original but its prototype is set to a clone of the original.
I can easily clone the original prototype like so:
// the original constructor function is assigned to the `type` variable.
const prototype = type.prototype;
const clonePrototype = Object.create(null);
const props = Object.getOwnPropertyNames(prototype);
for (let i = 0; i < props.length; ++i) {
const propertyName = props[i];
const propDescriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);
Object.defineProperty(clonePrototype, propertyName,
Object.getOwnPropertyDescriptor(prototype, propertyName));
}
The issue I'm having is how to create a constructor function now that has its prototype property set to the clonePrototype object.
If I do:
const newContructor = function() {};
Object.setPrototypeOf(newContructor, clonePrototype);
then newConstructor ends up with __proto__ set to the clonePrototype object, and the prototype property unchanged. I'd like to leave __proto__ unchanged, and prototype set to the new value.
My goal is to clone this constructor function so that it constructs a copy of the original type that behaves just like the original, but has its own prototype.
How can I accomplish this?
Thanks!
I'm going to naively show you two solutions:
Answers your "how to" question directly (per comments)
The JavaScript way of producing the result
I say naively, because perhaps there is some use case that requires the cloning to occur (perhaps some time after the Type prototype has changed over time). But, given your code examples, the JavaScript way presumes unmodified prototypes.
So here is the first. Note the changes I made was to convert the function expression:
const newContructor = function() {};
To a function declaration:
function NewConstructor() {};
And since you Object.create'd the clone, I Object.assign'd it to the prototype.
function Type() {};
Type.prototype = {
a: 1,
b: 2,
c: function() {
console.log(this.a + " + " + this.b + " = " + (this.a + this.b));
}
}
const prototype = Type.prototype;
const clonePrototype = Object.create(null);
const props = Object.getOwnPropertyNames(prototype);
for (let i = 0; i < props.length; ++i) {
const propertyName = props[i];
const propDescriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);
Object.defineProperty(clonePrototype, propertyName,
Object.getOwnPropertyDescriptor(prototype, propertyName));
}
function NewConstructor() {};
Object.assign(NewConstructor.prototype, clonePrototype);
/********************************************/
let type = new Type();
const cloned = new NewConstructor();
type.c(); // prints 1 + 2 = 3
cloned.c(); // prints 1 + 2 = 3
Object.getPrototypeOf(type).a = 0;
// Alternative syntax that some will dislike and point out it should not be used
cloned.__proto__.a = 3;
type.c(); // prints 0 + 2 = 2
cloned.c(); // prints 3 + 2 = 5
// Here are the independent prototypes (or type.__proto__ and cloned.__proto__
console.log(Object.getPrototypeOf(type), Object.getPrototypeOf(cloned));
If the prototype is a pristine prototype when the cloning occurs, it is much more direct to use the prototype as a constructor itself. This allows you to use the new operator with your prototype to construct a Singleton instance of the prototype itself.
In this example you will see no cloning of the prototype. A singleton version of the prototype is created for each object that needs it as a prototype.
The mutation of each prototype is then observed as independent from one another:
function MyPrototype() {
this.a = 1;
this.b = 2;
this.c = function() {
console.log(this.a + " + " + this.b + " = " + (this.a + this.b));
};
}
function Type() {};
function NewConstructor() {};
Type.prototype = new MyPrototype();
NewConstructor.prototype = new MyPrototype();
/********************************************/
let type = new Type();
const cloned = new NewConstructor();
type.c(); // prints 1 + 2 = 3
cloned.c(); // prints 1 + 2 = 3
Object.getPrototypeOf(type).a = 0;
// Alternative syntax that some will dislike and point out it should not be used
cloned.__proto__.a = 3;
type.c(); // prints 0 + 2 = 2
cloned.c(); // prints 3 + 2 = 5
// Here are the independent prototypes (or type.__proto__ and cloned.__proto__
console.log(Object.getPrototypeOf(type), Object.getPrototypeOf(cloned));

Access variables like a text?

Let's say i got a variable Var123;
var x = "Var";
var VariableMixLOL = x + "123";
//so VariableMixLOL should be equal to Var123, ex. Var123 = "Abc", VariableMixLOL should be "Abc" too
How can I do this? Btw i'm using as3
PS: Added at Tags JS too because i think it's the same thing
One option is to use eval()
var x = "Var";
var Var123 = "lalaala";
var VariableMixLOL = eval( x + "123" );
Another option and the better one is to model such things in a JavascriptObject.
var x = "variable";
var variables = { "variable123" : "laalala"}; //OR variables = {}; variables["variable123"] = "laalala";
var VariableMixLOL = variables[ x + "123"];
Variable name as String can be used if you incorporate an object to which you store it.
For example:
var x = "Var";
var compoundVar = x + "123";
var obj : Object = {};
obj[compoundVar] = 7;
//Now you can call the variable like this
trace(obj.Var123); //7

If I have a variable, assigned to the value of a function call, can that variable be updated if the function call's parameters are changed?

If I have a function, like this:
function f(x,y){
return x + y;
}
And if I have variables of parameters I want passed to f:
var parameter1;
var parameter2;
If I assign this function call to a variable:
var functionCallValue = f(parameter1,parameter2);
How can I ensure that functionCallValue changes depending on different values I assign to the variable parameter1 and parameter2?
I suppose what you need is a closure.
var servant = function(x, y) { return x + y; };
var param1 = 40;
var param2 = 2;
var master = function() { return servant(param1, param2) };
var result = master(); // 42.
param1 = 2;
param2 = 40;
var anotherResult = master(); // still 42, because that's really the answer!
functionCallValue is assigned the result (returnvalue) of your function f. (The function is called, the value calculated and the result handed over to your variable.) Thus functionCallValue does not automatically update, if you change the parameters (which would make no sense at all), you need to call the function again with the altered parameters.
For something like an auto-update you need a closure like this:
var asdf = (function(){
var param1 = 1;
var param2 = 2;
var result = param1+param2;
function compute(){
result = param1 + param2;
}
return{
param1:function(x){
param1 = x;
compute();
},
param2:function(x){
param2 = x;
compute();
},
result:function(){
return result;
}
}
})();
console.log(asdf.result()); // logs 3
asdf.param1(3);
console.log(asdf.result());​ // logs 5
Demo

javascript re-define a variable

I'm getting stuck somewhere (as newbies do). Is it ok to re-define a variable once it has been trimmed and tested for content?
function setarea() {
var dbasedata = document.forms[0]._dbase_name.value;
dbasedata = dbasedata.toUpperCase();
dbasedata = dbasedata.replace(/\s/g, "");
dbasedata = dbasedata.remove("UK_CONTACTS", "");
if (dbasedata != "") {
_area.value = _dbase_name.value;
}
else var dbasedata = document.forms[0]._dbase_name.value;
dbasedata = dbasedata.toUpperCase();
dbasedata = dbasedata.replace(/\s/g, "");
if (dbasedata.indexOf("UK_CONTACTS")>-1 {
var dbaseterm = "UK_CONTACTS";
else var dbaseterm = "";
}
It makes no sense to use var more than once for the same variable in the same scope. Since all var x; are hoisted to the top of the scope every additional var on that variable will be a no-op.
Assigning a new value is fine though - they are variables and not constants after all.
function x() {
var x = 123;
foo();
x = 456;
var y = 'hello';
var x = 678;
}
is actually this internally:
function x() {
var x, y; // both are === undefined
x = 123;
foo();
x = 456;
y = 'hello';
x = 678;
}
Yes, you can do this and it is legal.
It may 'work', but isn't recommended. You don't need to redeclare it.
Probably want to run your code through JSLint . There are a few tidyness/bracing issues you would want to address.

How do I interpolate a variable as a key in a JavaScript object?

How can I use the value of the variable a as a key to lookup a property? I want to be able to say: b["whatever"] and have this return 20:
var a = "whatever";
var b = {a : 20}; // Want this to assign b.whatever
alert(b["whatever"]); // so that this shows 20, not `undefined`
I am asking if it's possible during the creation of b, to have it contain "whatever":20 instead of a:20 where "whatever" is itself in a variable. Maybe an eval could be used?
This works in Firefox 39 and Chrome 44. Don't know about other browsers. Also it doesn't work in nodejs v0.12.7.
var a = "whatever";
var b = { [a]: 20 };
console.log(b["whatever"]); // shows 20
That is, to interpolate a variable, enclose it in brackets.
I'm not sure if this is a part of any standard. Originally, I saw such syntax here: https://hacks.mozilla.org/2015/07/es6-in-depth-classes/ where the author defined:
[functionThatReturnsPropertyName()] (args) { ... }
I'm also not sure if you should use that syntax. It's not widely known. Other members on your team might not understand the code.
var a = "whatever";
var b = {};
b[a] = 20;
alert(b["whatever"]); // shows 20
var a = "whatever";
var b = {a : 20};
b[a] = 37;
alert(b["whatever"]); // 37
'a' is a string with the value 'a'. a is a variable with the value 'whatever'.
Great question. I had a time trying to figure this out with underscore but the answer couldn't be more simple:
var a = "whatever";
var b = {a : 20};
var array = [a, b]
var answer = _.object([[array]])// {whatever: {a:20}}//NOTICE THE DOUBLE SET OF BRACKETS AROUND [[array]]
I hope this helps!
Try this:
var a = "whatever";
var c = "something";
var b = {whatever : 20, something: 37};
alert(b[a]); // Shows 20
alert(b[c]); // Shows 37
Here is the fiddle.
Or if I understand from the below comments correctly, try this:
var a = "whatever";
var b = {a : 20};
alert(b.a); // Shows 20
To show all options, I want mention the CoffeeScript way of doing this, which is:
var a = "whatever";
var b = (
obj = {},
obj["" + a] = 20,
obj
);
alert(b.whatever); // 20
Although I prefer:
var a = "whatever";
var b = {};
b[a] = 20;
alert(b.whatever); // 20

Categories

Resources