What am I missing in this Javascript Array behavior? [duplicate] - javascript

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Array.prototype.fill() with object passes reference and not new instance
(7 answers)
Closed 9 months ago.
I tried this in the chrome dev tools console:
let a = [[null,null],[null,null]]
function na(){ return Array(2).fill(Array(2)) }
let b = na();
console.log(JSON.stringify(a))
// [[null,null],[null,null]]
console.log(JSON.stringify(b))
// [[null,null],[null,null]]
So far, so good. I was expecting both a and b with the same values and strucuture. Then I wanted to test a small function that should append an extra value in each line:
function add(x) { x.map( line => line.push(null) )}
add(a)
console.log(JSON.stringify(a))
// [[null,null,null],[null,null,null]]
add(b)
console.log(JSON.stringify(b))
// [[null,null,null,null],[null,null,null,null]]
// ?! I was not expecting this extra value here...
Well, that was unexpected.
Why is that extra null appearing in add(b) ?

function na(){
return Array(2).fill(Array(2))
}
na() fills the empty Array(2) with shallow copies of the second Array(2) object.
As a result changing values in any of the clones changes the Array's value everywhere.
a = Array(5).fill(Array(3))
a[0][0] = 1
a[0][1] = 2
a[0][2] = 3
console.log(JSON.stringify(a))
So because b has 2 elements and you are using .push() to add an element to b for each of the (same) arrays, 2 new elements are added to the array.

Related

Why are arrays passed by reference, but not singular variables? What is the benefit of this? [duplicate]

This question already has answers here:
Is JavaScript a pass-by-reference or pass-by-value language?
(33 answers)
Closed 8 months ago.
Code 1 prints "florence"
let name = "florence";
function test (arr) {
arr += " and the machine";
}
test(name);
console.log(name);
Code 2 prints "florence and the machine"
let name = ["florence"];
function test (arr) {
arr[0] += " and the machine";
}
test(name);
console.log(name);
I understand that the outcomes are different because Code 1 passes by value, and Code 2 passes by reference. I'm just trying to understand why.
What is the benefit of retaining the mutability of an array, but not a variable?
CAN YOU pass variables by reference?
CAN YOU pass arrays by value (without a workaround)?
When you pass an object (array), the referrnce to the object is passed, so in your case arr points to name.
arr[0] however now points to the value at name[0], and name[0] is modified accordingly.
Changing arr has no global effect:
let name = ["florence"];
function test (arr) {
arr[0] += " and the machine";
arr=[];
}
test(name);
document.write(name);

JavaScript array expressions return object literal in one line [duplicate]

This question already has answers here:
ECMAScript 6 arrow function that returns an object
(6 answers)
Closed 3 years ago.
Its known that someone can make a one-line array function like this to return the single value:
var func = (x) => x + 1 //func(2) == 3
and you can also make multi-line array-functions, whose values need to be manually returned:
var funcMultiline = (x) => {
var result = 1;
result += x;
return result;
}
funcMultiline(4) == 5; //true
So the question:
let's say I want to return a new object in one line, if I use the brackets, then the array-function is treated like a multi-line function, and doesn't actually return the object-literal. Is there any direct way to create an object literal in, lets say, a map function? Like:
[...Array(25)].map(e => {x: 5, y:10}) //this is a syntax error, but how can I make this work
Returning object literals using the concise body syntax params => {object:literal} will not work as expected.
You have to wrap the object literal with parenthesis:
var res = [...Array(25)].map(e => ({x: 5, y:10}))
console.log(res);

Override print representation of a JavaScript array [duplicate]

This question already has answers here:
Does console.log invokes toString method of an object?
(4 answers)
How do I override the default output of an object?
(2 answers)
Closed 5 years ago.
I'm trying to take an array object and change its print representation - just of that object, not of all arrays in the program. I hoped setting the toString property would do the job, but it doesn't:
var a = [1, 2, 3]
// Prints using the default representation
console.log(a)
// Try to override toString
a.toString = function() {
return 'some new representation'
}
// Still uses the default representation
console.log(a)
What am I missing?
var a = [1, 2, 3];
// Prints using the default representation
console.log(a);
// Try to override toString
a.toString = function() {
return 'some new representation'
}
// append blank string to invoke toString function
console.log(""+a);

Is it possible in Javascript to get the name of a variable? [duplicate]

This question already has answers here:
Determine original name of variable after its passed to a function
(9 answers)
JavaScript: Get Argument Value and NAME of Passed Variable [duplicate]
(7 answers)
Closed 7 years ago.
I know this is completely useless, but I'm nonetheless curious. Is it possible to do something like the below?
function getVariableName ( v )
{
// .... do something .....
// return the string "v"
}
var x = 69;
var y = "somestring";
console.log(getVariableName(x)); // prints "x" to the console
console.log(getVariableName(y)); // prints "y" to the console
function getArgNames(fn) {
var matches = fn.toString().match(/\(([a-z_, ]+)\)/i);
if (matches.length > 1) {
return matches[1].replace(/\s+/g, '').split(',');
}
return [];
}
That will return an array of the names of all arguments passed in to the function.

Using a string to return a variable [duplicate]

This question already has answers here:
How to find JavaScript variable by its name
(7 answers)
Closed 8 years ago.
I'm trying to find a way of using a string to refer to a variable.
Here is an example using jQuery:
var array = [1,2,3];
$('.array').click(function(){
var foo = $(this).attr('class');
return foo[1];
});
I want this to return the number '2' -
but as foo is a string it will return the sub string 'r'.
edit - the answer I was looking for was:
var array = [1,2,3];
$('.array').click(function(){
var foo = $(this).attr('class');
return eval(foo)[1];
});
I don't know if this is quite what you mean, but a Javascript object can do this.:
foo = {}; // create object
foo["string"] = [1,2,3]; // now the list [1,2,3] can be referenced
// by foo.string, or foo["string"]
console.log(foo["string"][1]); // Output with string.
Is that what you mean?

Categories