Should I use eval() to make variable declaration dynamic? - javascript

I need to declare some variables. If I pass the variable name to a function it should declare all variable. (variable might be using for instantiating an object.)

Short answer — you should not.
Long answer.
It is a bad way, because eval is a really dangerous thing. You can read about problems here — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval.
Also, it can produce bad design of your application. Try to replace dynamic variable name with other solution. E.g., object property.
Let's look at the code-example:
function createObject(fieldName, value) {
return {
[fieldName]: value
}
}
In this piece of code, we don't use eval, but have object with dynamic key.

you can declare a variable dynamically without eval by using square brackets:
var variableName = 'someVariable';
someObject[variableName] = 'some value';

Related

Why am I unable to modify 'this' in this context?

In the following case, I would assume that the value of this (which is a string) could be modified to a different string. That way, I could emulate an array and simply write string_var.shift() to remove the first character of the string. However, from what I've gathered, this is immutable. I'm not sure how else I would approach this problem if I am unable to modify the value of the string. I could of course return the result but then I'd have to write string_var = string_var.shift() which has a different syntax to the array function of the same name and would ultimately be confusing.
Object.defineProperty(String.prototype, "shift", { value: function() {
this = this.substr(1)
}})
You can't modify this since it is a keyword, not a variable. Just like function or class
you can assign that value to another variable:
var self = this.substr(1)
instead
Also, note that this context is the inner function at this point.
There are two reasons why the following code won't work. this is not a variable, it is a property of an execution context (global, function or eval) that, in non–strict mode, is always a reference to an object and in strict mode can be any value. It is syntactically invalid to assign anything to it.
But more importantly, it is impossible to implement a mutation method on the String interface, as strings, booleans and numbers are all immutable within Javscript, as per the ECMAScript specification. When you "mutate" a value, such as in the context x += 5, behind the scenes you are creating a new value, not modifying the original one.
Well you can return the value after doing some operations on it
String.prototype.shift = function() {
return this.slice(1);
};
var a = "abcdef";
console.log(a);
a = a.shift();
console.log(a);
Note:
modifiying the prototype of the language itself is considered to be bad practice

JavaScript: Set name of inner function to be name of variable it's assigned to

I'm trying to do some composition and I'm using the function name to assign a key in an object. Thus, I have a higher order function kind of like so:
function doThing(fn) {
return function (...args) {
return fn(...args);
};
}
And I'm assigning the result of the outer function to a variable:
var coolThing = doThing(someFunction);
I want coolThing.name to equal 'coolThing'.
Now I'm pretty sure that is impossible because once the inner function is returned, the name is set to an empty string and can no longer be changed. But I'm wondering if I can elegantly make something like it work without skirting the lexer or anything awful like that.
Just wrapping doThing(someFunction) with another function would make it work, but that ends up making it no better than what I had started with.
It doesn't have to be the name property that I'm using, but the function needs to have some property that get's its value from the name of the variable.
Any ideas, or am I trying to be too cute here?
I'm pretty sure that is impossible
You're right. The variable name is not accessible programmatically, and for sure not inside doThing. Even for function declarations and assigned anonymous function expressions, the implicitly assigned .name property is something that the runtime does extract from the source text for exactly those syntactic constructs. It can not be intercepted and should only be used for debugging purposes anyway.

What is the different between a parameter and a local variable?

Apologies for what must seem like a very stupid question.
I'm currently working through codecadamy, and this is throwing me off:
var greeting = function(name) {
name = "sausage";
console.log(name);
};
greeting(name);
I understand that I will get sausage
Why don't I just write var name = "sausage";? What is the difference?
The name in function(name) is a parameter. That is, it is used to pass data into the function. But, parameters are local variables. Assigning a value to name inside the function is a little strange though. I would assume you want to do something like this:
var greeting = function(name) {
console.log(name);
};
greeting("sausage");
In this version of the code you are passing the value "sausage" into the function via the parameter name. This is useful because you can call the function many times and each time the function may print a different value depending on what you pass.
In your function definition:
function(name) {
name is already being declared. It is a parameter for the function. If you want to change name, you can, but you don't need to use var to declare it as a new variable.
On the other hand, if you wanted to add, say, flavor, you should use var then since it is not already defined.
var flavor = 'savory';
In this case, flavor is a local variable and name is a parameter. A parameter is a type of local variable that is declared with the function declaration, but a local variable isn't necessarily a parameter because it may be declared elsewhere in the function.
Parameters are a general programming construct and are necessary to do anything sane in the world programming (dealing with masses of global variables is not sane.
var name would declare a new variable in the function scope that would override the value of the parameter name, so you would not be able to use the parameter anymore.
The CodeAcadamy example is a bit strange because it's rare that you want to override a parameter's value -- especially before you have used it.
Technically, there is no real difference.
Without giving you the huge background here, you have to understand that in the underlaying implementation, a special object (not a javascript object, on C/C++ level) is formed which is called Activation Object (ES3) or Lexical Environment Record (ES5).
However, this hash / object structure is used to store
variables declared by var
formal parameters
function declarations
As you can see, both var variables and parameters are stored in this structure.
This construct is most likely used to have somewhat default values for not passed in arguments. In a real world example, this would probably look more like
var greeting = function( name ) {
name = name || 'default';
console.log( name );
};
greeting('john'); // 'john'
greeting(); // 'default'

Why we used "this" keyword in this snippet?

var someObject = {
someArray : new Array(),
someInt : 0,
Total: function(){
this.someInt = 0;//we used "this" keyword here, why?Cant we just say "someInt = 0"?
for(var i=0;i<this.someArray.length;i++){//and here..
var c = this.someArray[i];//again we use "this"
this.someInt += c.value;//also here
}
so why did we use "this" keyword? cant we just type the name of the variable?
The this keyword refers to the object on whose behalf the call is made later on, i.e. if you call the function like this:
someObject.Total()
then this will refer to someObject inside the function. Thanks to this keyword the function can modify someInt and read from someArray which are members of someObject. If you dropped this from the function body, all those references would be to global variables or variables local to the function body.
No, the statement someInt = 0 would not modify the someInt property of someObject. Instead, it would modify a property named someInt on the global/default object (window in a browser), which is obviously not want you want.
Note that (depending on how you intend to invoke the Total function) you could also write this as someObject.someInt. However, when calling the function like this:
someObject.Total()
...the value of this in the function is equal to someObject.
No, because the variable is not fully created. By using the 'this' keyword you can access a variable from itself.
Looks to me like it's just for clarity. Always using this. is probably a good practice when you don't use special naming conventions for instance variables vs. local variables (in other languages as well, not just javascript).
Even though it may not be required in this case, if you had a larger function, with lots of local and instance variables, it makes things much clearer when you distinguish.
In fact, Douglas Crockford in his Javascript The Good Parts, suggests not using this keywords in the code, for the functions from the object may be applied to other objects and this may cause errors. so it's better sometimes to use just variable names.
someInt is defined as a property of someObject. It would need to be defined as a variable in order to access it that way.
http://jsfiddle.net/Z7mSK/
Understand this keyword in detail HERE

Accessing variables from other functions without using global variables

I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.
If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?
I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
No one should yell at you for doing something like the above.
To make a variable calculated in function A visible in function B, you have three choices:
make it a global,
make it an object property, or
pass it as a parameter when calling B from A.
If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Consider using namespaces:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
Both local_function and global_function have access to all local and global variables.
Edit: Another common pattern:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.
What you're looking for is technically known as currying.
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.
I found this to be extremely helpful in relation to the original question:
Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
If another function needs to use a variable you pass it to the function as an argument.
Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.
If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.
Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...
Douglas Crockford wrote:
Jul 15 '06
"If you want to retrieve objects by id, then you should use an object, not an
array. Since functions are also objects, you could store the members in the
function itself."
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"The object can be obtained with"
objFacility.wlevine
The objects properties are now accessable from within any other function.
I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.
Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.
You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).
Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):
How to get a variable returned across multiple functions - Javascript/jQuery

Categories