Using functions within conditionals - javascript

I've been doing Project Euler 'cause reasons. At one point, I found myself wanting to compare a value with the result of a function. I've since selected a different solution, but it's left me curious. How would this work? If I were to do something like:
//javascript
if x == mathyFunction(10){
//do this
}
function mathyFunction(y){
if(y>0){
mathyFunction(y-1);
return y;
} else {
return y;
}
}
I'm aware that this isn't tail recursive or anything fancy, I'm mostly just curious how the logic works behind this.
How would the computer interpret it? Would it return true if any one of the values == x or would it only return true if all the values == x. Experimentation has left me guessing, though I'll keep digging.

You didn't specify which language you're asking about, but assuming the usual semantics of the return statement, a function can't return more than once. So if by "return all values individually", you meant something like this:
function f() {
return 1;
return 2;
...
}
Then everything after the first return is just dead code and it's the same as if the return 1 was the only return statement in there. A function call has exactly one value and that value is what you're comparing against.
If you meant that mathyFunction returns a list or other collection object, which contains the values between x and y, then x will be compared to that list. Again the semantics will depend on the language, but in most languages comparing a number to a list will either be a type error or just false.
If by returning the values individually you were referring to a yield statement (like C#'s yield return or Python's yield), then the result of the function is going to be some kind of iterator object and the same thing as in the previous paragraph applies.

Related

Is it good practice to override function parameter value?

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`;
}

Can somebody explain the use of statement values Javascript ECMAScript?

I am new to Javascript and have noticed that statements have values:
> x = 1
<- 1
> if (false) {
x=1;
}
else { x=2 };
<- 2
Could somebody explain why statements have values what they are used for in real applications, since functions need to return values explicitly via return.
Is this related to the notion of completions, which are associated with values, irrespective of their type (Normal or Abrupt) ?
Normal completion values primarily come up in user code via eval, though even then it's not super common. The return value of eval is the final completion value of the executed statements. Since eval executes a list of statements, when you run eval("4") === 4 for instance, you're not evaluating an expression for a value specifically, automatic-semicolon-insertion is kicking in, so you're actually running eval("4;") and then getting the completion value of that statement.
In the future, completion-value semantics will also likely affect the do expression proposal which would allow for code like
const value = do {
if (false) {
1;
} else {
2;
}
};
value === 2;
You could almost look at your examples as a nice side-effect of the general completion value semantics in the language, as well. When you throw or return from a function, the spec language itself for instance, still traverses the whole function. Returning or throwing essentially says "the completion value is this value" with the type "return" or "throw". So if you had
function fn()
if (false) {
return 1;
} else {
2;
}
}
one branch of the "if" produces an abrupt completion with value 1, and the other produces a normal completion with a value 2.
When execution (from the spec standpoint), gets to the end of the function itself, it will say "is this a return/throw, if so, propagate it to the caller of the function. If it is a normal completion, it will just discard the value and return undefined.
So really, the fact that there is a completion value is exactly the same as having a return value or throwing an exception value, from the standpoint of the spec, it just happens to discard the value in most cases if it is a non-abrupt completion.

Conditional returns or single variable return

I was wondering what if there's any preferable way of returning values conditionally.
And if not, if it makes any different for minified Javascript.
I was checking Google Javascript Style guide and they don't name anything about the issue. Same with Airbnb guidelines
Using multiple conditional returns:
function demo(x, y) {
if (x < y) {
return getX();
} else if (x === y) {
return 'equal';
}
return getY();
}
Or having a single return with and making use of a variable:
function demo(x, y) {
var position;
if (x < y) {
position = getX();
} else if (x === y) {
position = 'equal';
} else {
position = getY();
}
return position;
}
The following is a definition of the return statement.
The return statement stops the execution of a function and returns a value from that function.
Clearly, a conditional return would have to include a condition before that return.
About preference, as the word implies, it is really is a matter of habits.
If you're used to one syntax from, say, another language, or you just like it better - use it, as it will probably reduce syntax errors.
About minifying the code, I believe the switch/case syntax best works for simple conditions, and the ternary operation fits well for two-side conditions.
(Caution! philosophical paragraph ahead)
But again, in the end, the important thing, I believe, is that you will understand the code you write. And, with experience, you will find what suits you best.
You should concern yourself with readability. Write the code in the way that is most understandable. If you are returning from with a deeply nest condition that is likely to be confusing to future read, but if you have a series of early exits at the start of your function that is likely to make the code more readable (when compared to deep nesting). Break up big functions and leave mangling to the compilers. The Closure Compiler will produce the same results for either of your examples.
Examples:
http://closure-compiler.appspot.com/home#code%3D%252F%252F%2520%253D%253DClosureCompiler%253D%253D%250A%252F%252F%2520%2540compilation_level%2520SIMPLE_OPTIMIZATIONS%250A%252F%252F%2520%2540output_file_name%2520default.js%250A%252F%252F%2520%2540formatting%2520pretty_print%250A%252F%252F%2520%253D%253D%252FClosureCompiler%253D%253D%250A%250Afunction%2520demo1(x%252C%2520y)%2520%257B%250A%2520%2520%2520%2520var%2520position%253B%250A%250A%2520%2520%2520%2520if%2520(x%2520%253C%2520y)%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520position%2520%253D%2520getX()%253B%250A%2520%2520%2520%2520%257D%2520else%2520if%2520(x%2520%253D%253D%253D%2520y)%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520position%2520%253D%2520'equal'%253B%250A%2520%2520%2520%2520%257D%2520else%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520position%2520%253D%2520getY()%253B%250A%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520return%2520position%253B%250A%257D%250A%250Afunction%2520demo2(x%252C%2520y)%2520%257B%250A%2520%2520%2520if%2520(x%2520%253C%2520y)%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520return%2520getX()%253B%250A%2520%2520%2520%257D%2520else%2520if%2520(x%2520%253D%253D%253D%2520y)%2520%257B%250A%2520%2520%2520%2520%2520%2520%2520return%2520'equal'%253B%250A%2520%2520%2520%257D%250A%2520%2520%2520return%2520getY()%253B%250A%257D
Use ternary/conditional operator.
In Javascript conditional operator can evaluate to an expression, not just a statement.
var result = x < y ? getX() : getY();
This starts evaluation from left and if your condition meets criteria then result will be the first portion otherwise result would be second portion.
For more conditions you have to use it like
var result = IsYoungerThan18 ? serveMilk() : IsYoungerThan21 ? serveBear() : serveWine();
So in your case it should be
var result = (x < y) ? getX() : (x == y) ? "equal" : getY();

How does this "if" without operators work?

I am relatively new to Javascript and am working through ch. 5 of Eloquent Javascript. I came across some code that I don't quite understand. I know HOW it works (the general method and steps), but I don't understand WHY it works.
The code is here:
function filter(array, test) {
var passed = [];
for (var i = 0; i < array.length; i++) {
if (test(array[i]))
passed.push(array[i]);
}
return passed;
}
Basically the function takes the element the 'for loop is iterating over' from the array, and compares it to the test parameter.
I am wondering how/why this works:
if (test(array[i]))
There is no || && or other 'comparison operators'. How does it compare values with only using parenthesis?
How is test compared to the array[i] value with no operators?
Link to file: http://eloquentjavascript.net/05_higher_order.html
go to 'Filtering an Array' exercise
Thanks!
Whatever is inside the parentheses of an if statement will be evaluated. If the result is falsy (false, 0, "", NaN, null, undefined) it fails and if the result is truthy (everything else) it passes. So if your if statement contains a function call if (test(something)) {}, then the if statement just says if the result of the function call is truthy then pass.
Also, && and || are not comparison operators, they are boolean operators. They just connect the result of two statements, like true || false which evaluates to true.
I am not quite sure, but I think this is a custom function. Most likely there is some comparison there and the result of the function is True/False. If you give us the whole code we could explain it better to you.
This code is accepting a test parameter that is what is called a "predicate function" i.e. a function that given an element will return true or false.
It's going to be used for example with
var big_numbers = filter(numbers, function(x){ return x > 100; });
i.e. the expected parameter test is actually code.
In Javascript passing code is very common and idiomatic. It's something that is more annoying in other languages that don't support the concept of "closure" and of "nested function", forcing all code to live at the top level, being given a name and to have no context (e.g. the C language).
'test' here is a function, not a value. In Javascript, each function is an object and can be passed as parameter. In this case, test is a function that take one parameter and return true or false base on the parameter value.
So in the for loop, test function is called with each array element and if the result is true, it will be store in another array. Eventually, passed elements would be return to the function caller.

Confused about Javascript. A boolean function can act as a void function?

I'm trying to refresh some Javascript knowledge for an upcoming interview. I was reading a blog that says
"The delete operator returns true if the delete was successful."
and then shows an example of it in use:
var christmasList = {mike:"Book", jason:"sweater" }
​delete christmasList.mike; // deletes the mike property​
In that example it looks like delete is used in the manner that a void function (in the general programming sense -- I know that JS doesn't require declarations like void) would be.
Can someone explain to me, or give me a link to, the documentation that explains how JS functions can act with different return values, and does such require separate implementations for each return value?
You can check the Delete operator which says:
If desc.[[Configurable]] is true, then
Remove the own property with name P from O.
Return true.
Note that delete only works for properties of objects. Also a good read:- JavaScript Delete() Only Affects The Referenced Object Regardless Of Prototype Chain
In that example it looks like delete is used in the manner that a void function
The delete operator is not a function, it is an operator. It deals with properties of objects, not their values.
Functions are something else, but since you asked:
Can someone explain to me how JS functions can act with different return values
JavaScript is loosely typed. Functions don't care about the types of values unless they need to, and (most of the time) conversion between types is handled by operators.
If a function needs to are about what it is operating on, then it has to examine the value to see what it is.
For example:
function myFunction(myArgument) {
if (typeof myArgument === "function") {
return myArgument();
} else {
return myArgument;
}
}
A function can return any value it likes.
function string_or_number() {
if (Math.random() > 0.5) {
return 1;
} else {
return "1";
}
}
Strongly typed languages care about what type of value a function returns and what type of value is passed into an argument.
Loosely typed ones simply don't. There's nothing special about it from the point of view of someone using the language.
It shunts most of the complexity about having to care about types to the compiler author instead of the user of the compiler (who just has to care that, if a function is designed to do something to a duck, what they pass is sufficiently like a duck to not break the function).
As others note, delete is technically an operator and not a function; for our immediate concerns, however, the difference is academic, as the operator's behavior is the same as that of many functions used for their side effects (which is to say, void functions). Both the rule of the language and the conventions of their use are simple.
Rule
All functions provide a return value; if no return statement is reached, this will be undefined
Conventions
Since we always get a return value, we can take advantage of it to improve our programs. There are two conventions; which one should be used depends on the use case.
Return a boolean, signalling success or failure
Return some object being operated on
Option 2 is most useful for methods on objects: if our method changes the state of the object and then returns the object, we can bundle several changes into a single line of method calls: object.change1().change2().change3(newVal);
Option 1 is most useful when we want to use the success or failure of an operation to determine program flow; maybe we want to throw an exception if the property was not deleted but continue normally if it was. Then we can use if (delete object.property) to attempt to delete the property and branch into success/failure cases immediately.
From the MDN on the delete operator:
Throws in strict mode if the property is an own non-configurable property (returns false in non-strict). Returns true in all other cases.
I can't make it simpler than that. Aside from a small example:
alert(delete window.window)
alert(delete window.foobar)
alert(delete window.alert)
Javascript functions always return ambigious values. One function can return boolean, string, object, array or HTMLElement.
There is no fixed type.
function masterSwitch(input) {
switch(input) {
case 0 : return "Hello";
case 1 : return 0xdead;
case 2 : return 0.00042;
case 3 : return document.createElement("DIV");
case 4 : return true;
case 5 : return window;
case 6 : return this;
case 7 : return null;
default:window.alert("Please specify input from 0 to 8");
}
}
<input type="text" id="output"> <SELECT onchange="document.getElementById('output').value = typeof masterSwitch(this.selectedIndex);">
<option>string</option>
<option>int</option>
<option>float</option>
<option>HTMLElement</option>
<option>boolean</option>
<option>window</option>
<option>this</option>
<option>null</option>
</select>

Categories