Is it good practice to override function parameter value? - javascript

In JavaScript consider I am trying to append a new value and return it.
I have below example regarding overriding parameter value
The below function receives a string value as param and overriding the param with new value and returning it.
function test(value) {
value = value + "hi";
return value;
}
console.log(test("Hello"));
The below function receives a string value as param. I would like to append a new value and return it. So I assigned value to a local variable and then appended strong to a new variable and returning it.
function test(value) {
let temp = value;
temp = value + "hi";
return temp;
}
console.log(test("Hello"));
I am calling it and passing value
test(“Hello”);
Which one is recommended from above?

It's purely a matter of style. Some people think you should leave parameter values alone, others think it's fine to change them.¹
From a practical perspective, it doesn't cause any harm. That is, there is no hidden side-effect to doing so. In particular, since JavaScript is purely pass-by-value, reassigning the parameter can't have any effect on whatever argument was used to fill in that parameter:
function test(value) {
value = value + "hi";
return value;
}
let a = "let's say ";
let b = test(a);
console.log(b); // "let's say hi"
console.log(a === b); // false, `a` was not modified
Your version with temp can be simpler, though:
function test(value) {
let temp = value + "hi";
return temp;
}
(or even
function test(value) {
return value + "hi";
}
but I figure it's highly simplified for the question.)
¹ (I happen to be in the latter camp, but that's neither here nor there.)

Yes, this is not at all wrong and is often done by many programmers across many languages. It is a common practice.
You can use it in cases where you want to use the parameter value inside the function but after making certain modifications to it.
For example, I might want to add two numbers using a function add(a, b) where a and b can be strings or integers or floats.
But just to be sure about it, I can define the add function in the following way:
function add(a,b) {
a = parseFloat(a);
b = parseFloat(b);
return a + b;
}
and this is perfectly fine. This way I can be always sure that there will be no exceptions thrown or in case parameters were passed as strings, it doesn't returns 12 (if I said add(1,2)) when really it should have been 3.
By making parameter overriding a common practice and incorporating it into your coding style, you spare the browser from creating or defining new variables just to modify those variable values. This might not mean much in small applications, but in large scale heavy applications, it might make a noticeable difference especially on low end devices.

The short answer is: it's only a matter of style.
However, this isn't always right. When passing objects, they will be passed by reference, meaning that every change you'll make to the parameter will affect the original object:
const obj = {originalValue: true};
function modifyObject(input) {
input.originalValue = false; // The change happens here
return input; // So it will take place regardless of this line
}
console.log('before:', obj);
modifyObject(obj); // See? we don't even retrieve the return value
console.log('after:', obj);

If we were talking about Java, then creating a new variable would be good practice. As there is something called the Garbage Collector that collects unused variables, etc. and discards them. So keeping a link to the original variable wouldn't allow the collector to discard the variable. (I read this somewhere, but some people said to me it doesn't really work this way, so read more about this online if you want)
In JavaScript, however, it doesn't really matter. It depends on you. Your style. It also depends on the situation as it can be useful sometimes. But really it doesn't really matter. Do as you like.
If you want to simplify it you can do as #T.JCrowder said:
function test(value){
return value+ “hi”;
}
That's about it.

Using ES6 Template literals
function test(value){
return `${value} hi`;
}

Related

assign value to function parameter, is it safe to reuse function arguments?

Is it a bad practice to reuse function parameter variables?
const reformat = (phone)=>{
phone = phone.replace("-", ",")
//... more operation using phone
return phone;
}
is there any reason such reusage should be avoided? or is it always safe to continue such usage?
For strings, like in your example, it's fine. Some people may think it could get confusing if you're trying to debug and log that variable to the console sometime after it's been changed, but that's mostly subjective. Use your best judgement.
For objects, which are always passed by reference, you should avoid making changes in the function because those changes will still be present outside the function as well.
E.G.:
var myObject = {
message: "Hello, world"
};
function alertMessage(msgObj){
msgObj.message = "Hello moto";
alert(msgObj.message);
}
alertMessage(myObject);
// The object has changed.
console.log(myObject);
No it's not. And it's memory saving sometimes, since when you use another new variable, it will take up your memory. And the function process is much longer many transformations then it will be not a good practice to do. So according to your questions,
Yes, you can use the same variable inside the function (But make sure to consider what are the types that you refer when passing as arguments)
Re-usage should be avoided when you are using a object and that will change the content of the origin object.
different cases to take care:
// argument is not a reference ( string, numbers )
function add_5(num)
{
num += 5
return num
}
let initial_num = 10
let returned_num = add_5(initial_num )
console.log( `initial_num-> ${initial_num}, returned_num-> ${returned_num}`)
// argument is reference ( objects )
function directArgObj( obj)
{
obj.num += 5
}
let initial_obj = { num: 10, abc:'xyz' }
directArgObj(initial_obj )
console.log( `initial_obj-> ${JSON.stringify(initial_obj)} `)

Correct Syntax For Using The Returned Variable From A Function?

I have a function that returns a variable, I'd just like to know what's the correct syntax for doing something (such as doing math or writing a new variable using that returned variable.
Example Function:
function exampleFunction(number) {
var data_filter = number + number;
return data_filter;
}
The function returns data_filter, and I'd like to know what's the correct syntax for doing something with it, such as inputting it in another function.
What you have here is fine.
As one of the comment suggests typically you assign the result to a variable. Take a simple example here:
let myNumber = 10;
let myHalvedNumber = halveNumber(myNumber);
console.log(myNumber)
console.log(myHalvedNumber);
function halveNumber(numberToHalve){
return numberToHalve/2;
}
The best way to think about it in practice is to treat the function/input combination { f(x) } as a proxy for the result itself. This means that both of these examples are correct and how you choose to employ it is your own preference.
//These two approaches are identical and both valid:
//1) Assign to a variable for further use - typically better for variable re-use:
let myHalvedNumber = halveNumber(10);
aSecondFunction(myHalvedNumber);
//2) Use the result directly in a second call - typically shorter and arguably easier to maintain/read
aSecondFunction(halveNumber(10));
function halveNumber(myNumber){
return myNumber/2;
}
function aSecondFunction (myNumber){
console.log("the number is: " + myNumber)
}

Calling a function bypassing eval()

I am working with a Javascript code that uses eval function.
eval(myString)
The value of myString = myFunc(arg), I want to call myFunc directly without using eval.
I dont have any control over the function to call as I am getting that function as a String (here myString).
The arguments to that function is also part of the same string.
So, is there any way through which I can call the intended function without using eval?
I'm a bit skeptical of allowing users to provide function names at all, but... Assume you have the function name in a variable and the value of arg in a variable. Boom:
var myString = window[fn](arg);
arg is already presumably in an argument, so that's simple enough. The next part is exatracting the function name. Just a bit of regex:
var fn = /^([a-z0-9_]+)\(arg\)$/i.exec(str)[1];
if (fn && typeof window[fn] === 'function') {
window[fn](arg);
}
This does of course assume that the function is always in the global scope, but if it's not, you should be able to adjust accordingly for that. Also, my regex is just the first thing I came up with. It probably doesn't cover all possible function names.
If you wanted to limit the string to just a certain set of functions (and you almost certainly should), that becomes quite easy as well once you have the function name:
var allowedFunctions = {fn1: fn1, fn2: fn2, someOtherFunction: function() {} },
fn = /^([a-z0-9_]+)\(arg\)$/i.exec(str)[1];
if (fn && allowedFunctions[fn]) {
allowedFunctions[fn](arg);
} else {
// Hah, nice try.
}
(If arg isn't actually a variable name but is some kind of literal or perhaps an arbitrary expression, this gets a little more complicated and a lot less safe.)
JavaScript does not provide any way of calling a function represented as a string, other than using eval. There's nothing wrong about using it, though. Given that you have no other option.
Possibly you may try using Function:
var sure = function(s) {
return confirm(s);
};
var str = 'sure("Are you sure?")';
var rtn = new Function('return ' + str)();
alert(rtn);

creating variable names from parameters in javascript

I was wondering if it is possible to create variable names from parameters passed to a function in javascript. Something like this:
function createVar(number) {
var "number" + number;
}
createVar(1)
I'm new to Stack Overflow and programming, so any help would be appreciated.
You could attach this to the window object, but note it will be global. For example:
function createVar(varName, value) {
window[varName] = value;
}
createVar("test", "Hello World");
alert(test); // Outputs "Hello World".
It is possible to interpret Object as associative array where you specify index and get value by name of index ( hash ):
var x = Array();
x[number] = value;
Single variable name is for programmer, and the code would be hard to maintain and understand when you set variable dynamically in code.
Honestly, I don't see why this would ever be useful, because every time you want to use the variable you'd have to search for it with your number argument.
However, you can do it, albeit not the exact way you had described:
function createVar(number){
eval("var number" + number.toString() + ";");
}
however, this variable will only be accessible within the function, to make it global assign to the window object:
function createVar(number){
window["number" + number] = 15; // creates "global" variable
}
As I've stated before, however, I don't see this being useful, [i]ever[/i], if you want to stratify values by numbers you'd be much better off with an array.

getting the name of a variable through an anonymous function

Is it possible to find the name of an anonymous function?
e.g. trying to find a way to alert either anonyFu or findMe in this code http://jsfiddle.net/L5F5N/1/
function namedFu(){
alert(arguments.callee);
alert(arguments.callee.name);
alert(arguments.callee.caller);
alert(arguments.caller);
alert(arguments.name);
}
var anonyFu = function() {
alert(arguments.callee);
alert(arguments.callee.name);
alert(arguments.callee.caller);
alert(arguments.caller);
alert(arguments.name);
}
var findMe= function(){
namedFu();
anonyFu();
}
findMe();
This is for some internal testing, so it doesn't need to be cross-browser. In fact, I'd be happy even if I had to install a plugin.
You can identify any property of a function from inside it, programmatically, even an unnamed anonymous function, by using arguments.callee. So you can identify the function with this simple trick:
Whenever you're making a function, assign it some property that you can use to identify it later.
For example, always make a property called id:
var fubar = function() {
this.id = "fubar";
//the stuff the function normally does, here
console.log(arguments.callee.id);
}
arguments.callee is the function, itself, so any property of that function can be accessed like id above, even one you assign yourself.
Callee is officially deprecated, but still works in almost all browsers, and there are certain circumstances in which there is still no substitute. You just can't use it in "strict mode".
You can alternatively, of course, name the anonymous function, like:
var fubar = function foobar() {
//the stuff the function normally does, here
console.log(arguments.callee.name);
}
But that's less elegant, obviously, since you can't (in this case) name it fubar in both spots; I had to make the actual name foobar.
If all of your functions have comments describing them, you can even grab that, like this:
var fubar = function() {
/*
fubar is effed up beyond all recognition
this returns some value or other that is described here
*/
//the stuff the function normally does, here
console.log(arguments.callee.toString().substr(0, 128);
}
Note that you can also use argument.callee.caller to access the function that called the current function. This lets you access the name (or properties, like id or the comment in the text) of the function from outside of it.
The reason you would do this is that you want to find out what called the function in question. This is a likely reason for you to be wanting to find this info programmatically, in the first place.
So if one of the fubar() examples above called this following function:
var kludge = function() {
console.log(arguments.callee.caller.id); // return "fubar" with the first version above
console.log(arguments.callee.caller.name); // return "foobar" in the second version above
console.log(arguments.callee.caller.toString().substr(0, 128);
/* that last one would return the first 128 characters in the third example,
which would happen to include the name in the comment.
Obviously, this is to be used only in a desperate case,
as it doesn't give you a concise value you can count on using)
*/
}
Doubt it's possible the way you've got it. For starters, if you added a line
var referenceFu = anonyFu;
which of those names would you expect to be able to log? They're both just references.
However – assuming you have the ability to change the code – this is valid javascript:
var anonyFu = function notActuallyAnonymous() {
console.log(arguments.callee.name);
}
which would log "notActuallyAnonymous". So you could just add names to all the anonymous functions you're interested in checking, without breaking your code.
Not sure that's helpful, but it's all I got.
I will add that if you know in which object that function is then you can add code - to that object or generally to objects prototype - that will get a key name basing on value.
Object.prototype.getKeyByValue = function( value ) {
for( var prop in this ) {
if( this.hasOwnProperty( prop ) ) {
if( this[ prop ] === value )
return prop;
}
}
}
And then you can use
THAT.getKeyByValue(arguments.callee.caller);
Used this approach once for debugging with performance testing involved in project where most of functions are in one object.
Didn't want to name all functions nor double names in code by any other mean, needed to calculate time of each function running - so did this plus pushing times on stack on function start and popping on end.
Why? To add very little code to each function and same for each of them to make measurements and calls list on console. It's temporary ofc.
THAT._TT = [];
THAT._TS = function () {
THAT._TT.push(performance.now());
}
THAT._TE = function () {
var tt = performance.now() - THAT._TT.pop();
var txt = THAT.getKeyByValue(arguments.callee.caller);
console.log('['+tt+'] -> '+txt);
};
THAT.some_function = function (x,y,z) {
THAT._TS();
// ... normal function job
THAT._TE();
}
THAT.some_other_function = function (a,b,c) {
THAT._TS();
// ... normal function job
THAT._TE();
}
Not very useful but maybe it will help someone with similar problem in similar circumstances.
arguments.callee it's deprecated, as MDN states:
You should avoid using arguments.callee() and just give every function
(expression) a name.
In other words:
[1,2,3].forEach(function foo() {
// you can call `foo` here for recursion
})
If what you want is to have a name for an anonymous function assigned to a variable, let's say you're debugging your code and you want to track the name of this function, then you can just name it twice, this is a common pattern:
var foo = function foo() { ... }
Except the evaling case specified in the MDN docs, I can't think of any other case where you'd want to use arguments.callee.
No. By definition, an anonymous function has no name. Yet, if you wanted to ask for function expressions: Yes, you can name them.
And no, it is not possible to get the name of a variable (which references the function) during runtime.

Categories