I'm working on a fronted calculator project but i don't really understand a strange behavior in Javascript.
This is my script:
const keys = document.querySelectorAll(".number");
const screen = document.querySelector("#screen");
let number = screen.value;
keys.forEach((key) => {
key.addEventListener("click", (event) => {
let refresh = (number += key.textContent).toString();
console.log(number);
screen.value = refresh;
});
});
Someone can tell me why if i change this line
screen.value = refresh;
with this one
number = refresh;
my value on the screen does not update despite in my console it is updating?
Aren`t these two different names to call the same thing?
Thank you
This is caused by string variables being assigned a value instead of a reference. This means that when you call let number = screen.value it only sets number to the value screen.value has at that moment. But if you change one of them, the other remains the same.
This is true for primitive types like numbers, strings and booleans. Objects and array variables are assigned references, meaning that changing the object through one variable will be reflected in all other variables pointing to the same object.
This is because you are using this line:
console.log(number);
So you will first print 'number' variable and later you will update the value of this variable, so this is the problem
if you want to solve this you have to invert the order of the lines something like this:
screen.value = refresh;
console.log(number);
I hope I've helped ;)
Related
I'm experimenting with my very basic Javascript and I found a nice Tutorial on how to make a very basic calculator in JS.
I tried following along with the video but I didn't want to just "copy-paste" what he was writing so I stopped and tried to do what I thought was the logic code...WRONG!
Here the problem
Why this doesn't work?
function addNum() {
let first = document.querySelector('.first').value;
let second = document.querySelector('.second').value;
let result = document.querySelector('.resultt').value;
return result = first + second
}
I tried to assign the input related to the result to a variable but it doesn't work.
But when I do this: (as it was done in the tutorial)
function addNum() {
let first = parseInt(document.querySelector('.first').value);
let second = parseInt(document.querySelector('.second').value);
document.querySelector('.resultt').value=first + second;
}
So without assigning the result to a variable, it works.
Why?
When you do
let result = document.querySelector('.resultt').value;
you're copying the value from the value property to the result variable. There's no ongoing link between them after that, they each just contain the same string. That means later, when you do result = first + second, all you're doing is updating result; that has no effect at all on value.
So you have to assign back to value as you do in your second code block.
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`;
}
I can't solve exercise three and four. I would be very pleased to get some help. Thank you in advance!
function exerciseThree(str){
// In this exercise, you will be given a variable, it will be called: str
// On the next line create a variable called 'length' and using the length property assign the new variable to the length of str
// Please write your answer in the line above.
return length;
}
function exerciseFour(num1){
// In this exercise, you will be given a variable, it will be called: num1
// On the next line create a variable called 'rounded'. Call the Math global object's round method, passing it num1, and assign it to the rounded variable.
var num1 = rounded;
math.round (num1);
// Please write your answer in the line above.
return rounded;
}
These exercises are trying to teach you how to declare variables and how to assign values to them.
Variables are like little containers that hold values for you. For example, I can make a little container to hold your name. And since one of the ways to declare a variable in JavaScript is to use the var keyword, I could write something as following:
var name = "Sevr";
I made a container with var keyword and named it name. This name container now holds your name which is Sevr. Instead of typing Sevr over and over again you can now type Name over and over. But, this doesn't make much difference. Sevr and name both contain same number of characters. It makes more sense to have your variables contain information that you don't want to type over and over again.
So exercise three wants you to declare a variable named length and make it hold the length of any string that it is provided with.
function exerciseThree(str) {
var length = str.length
return length;
}
This function above takes a string, you make a variable named length that contains the length of that string.
Now if we pass it any string it will tell us what length they are. If we pass it your name Sevr and name and we will see that they both return 4:
exerciseThree("name") // 4
exerciseThree("Sevr") // 4
On the fourth exercise, the concept is the same. The exercise wants to teach you that you can make a simple variable name that can hold on to some complex value for you. This time it wants you to declare variable named rounded that holds on to the rounded value of a number.
function exerciseFour(num1) {
var rounded = Math.round(num1)
return rounded;
}
And, now if you pass a number with decimals to this function it will round it for you.
exerciseFour(4.5) // 5
These exercises are worded in a really confusing way. Where you getting them from?
Anyway, here're the answers, hope they help:
function exerciseThree(str){
// In this exercise, you will be given a variable, it will be called: str
// On the next line create a variable called 'length' and using the length property assign the new variable to the length of str
var length = str.length
// Please write your answer in the line above.
return length;
}
function exerciseFour(num1){
// In this exercise, you will be given a variable, it will be called: num1
// On the next line create a variable called 'rounded'. Call the Math global object's round method, passing it num1, and assign it to the rounded variable.
var rounded = Math.round(num1)
// Please write your answer in the line above.
return rounded;
}
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.
I am trying to get the values of several fields & add them together & in my testing I am having problems. I have this code:
var count;
function calculate() {
// Fix jQuery conflicts
jQuery.noConflict();
count = 0;
jQuery('.calculate').each(function() {
var currentElement = jQuery(this);
var value = currentElement.val();
var count = count + value;
alert(count);
});
}
I enter in the value of "9" in my first field & when the first alert triggers I get "undefined9"; all the other values are currently set to "0"; when it triggers again I always get "undefined0".
Why am I getting the "undefined" bit & why is it only returning the value of the current field & not adding them together?
You are dimensioning the count value inside the loop, essentially setting it to undefined first in each iteration.
You want to remove the var within the loop. This way, it doesn't have scope to the anonymous function and JavaScript will look at the parent function for its declaration.
It may also be a good idea to parseInt(count, 10) the number first, because JavaScript overloads the + operator to mean arithmetic addition and string concatenation, and you wouldn't want count to be "0something".
Finally, count += value is easier to read :)
You're accidentally re-declaring count:
var count = count + value;
should be:
count = count + value;
The count declared in the inner-most scope (that of calculate) will hide the other one (this is called "shadowing" of variables).
The reason you get "undefined9" is because the default value of the newly-declared count variable is undefined; when you add to it, it sees an undefined value on the left, and a number on the right, and decides that string concatenation is the best way to perform the addition, resulting in the string "undefined9".
It has to guess at your intended meaning since + is overloaded to mean both numerical addition and string concatenation; in this case, it guesses wrong.
You're defining count in two different scopes - the calculate function, and then in the function that each is using. You may want to have the second count be named something else, or at least don't redeclare it.