How to get the the variable name from within a function in this example:
// it should return A
var A = function(){ console.log(this.name); }
Is there something like this?
That function is anonymous; it has no name. You could, however, give it a name:
var A = function a() {};
Then its name is accessible via Function.name:
var A = function a() {};
A.name
> 'a'
I know this is an old thread, but still in search results. so just for reference:
a solution could simply be using the stacktrace.
var stack = new Error().stack;
use trim and split to get to the desired values.
No, there is nothing like that in Javascript. That function is anonymous, so it has no name, and what you want is ambiguous because the function could just as easily have any number of variables referencing it like:
var a, b, c, d;
a = b = function(){ console.log(this.name); };
c = b;
d = c;
a = b = 5;
// a and b no longer refer to the function, but c and d both do
What is it you are actually trying to accomplish? I'm sure there is another way to achieve it.
It is possible in recent versions of Chrome and Firefox as follows. I only recommend this for debugging purposes (e.g. javascript tracing in non-production)
var myNameInChrome = /.*Object\.(.*)\s\(/.exec(new Error().stack)[0];
var myNameInFF = new Error().stack.split("#")[0];
Related
In this console:
When B is set to A but A was destroyed afterwards, B.b() throws an error because A is truly undefined.
How can one avoid this?
PS: I am aware that I can simply return this (or change the function in some way) but that doesn't fulfill my purposes.
EDIT: How do I 'localise' and somehow tell javascript that by A, I mean B even if A is undefined, WITHOUT ALTERING THE FUNCTION ITSELF?
You should change your A to look like the following:
let A = {
a: "a",
b: function() {
// change A.a to this.a
return this.a;
}
};
Right now since it references A when you destroy A Even though B is already equal to A the b method still needs the original A to exist. Swapping it for this will fix the issue.
The way the question and example is written that "error" cannot be avoided. return A.a; will and SHOULD be undefined based on your example because you are assigning A = undefined;
Also, if you are trying to clone an object, there are a couple of other options you should look into like:
let B = JSON.parse(JSON.stringify(A));
let B = Object.assign({}, A); MDN
Javascript classes
And maybe check out this answer: How do I correctly clone a JavaScript object?
To the new viewers, if you want to do this without altering the function:
var A = (function() {
var A = {a: 90, b: function() { return A.a }}; // same object as in the Q
return A;
})()
console.log(A.b()) // 90
var B = A;
A = undefined;
console.log(B.b()) // Also 90
B.a = 89;
console.log(B.b()) // 89
Assume I have code :
var a = {};
var b = {};
var c = a;
Obviously a !== b and a === c however it is very hard to see at a glance which variables refer to the same object. Is there a way to get the Chrome devtool to show something akin to a reference hash or similar so we can, at a glance, determine which variables refer to the same object?
I am aware of the rules regarding equality of JavaScript objects, my question is whether Chrome devtools offers any help in debugging so we don't have to do things like write manual a === b in the console to determine what equals what but rather see equal variables through visual inspection of watches or when hovering over variables.
I've not seen anything in Chrome that does something like that,.
But if you don't mind installing a simple utility method, you could implement your own referencing system.
You could also easily extend this to show referencing on Objects using Object.entries etc.
const refs = new WeakMap();
let count = 0;
function showRef(obj) {
const g = refs.get(obj);
if (!g) {
count++;
refs.set(obj, count);
return count;
};
return g;
}
const a = {};
const b = {};
const c = a;
const z = {a,b,c: {}};
console.log(`a = ${showRef(a)}`);
console.log(`b = ${showRef(b)}`);
console.log(`c = ${showRef(c)}`);
console.log(`z.a = ${showRef(z.a)}`);
console.log(`z.b = ${showRef(z.b)}`);
console.log(`z.c = ${showRef(z.c)}`);
What is the difference of accessing variables inside the function by as argument and without argument?
var a = 1;
var b = 2;
function x() {
var c = a + b;
console.log(c)
}
function y(a, b) {
var c = a + b;
console.log(c)
}
The key difference here is that y does not use anything other than the arguments provided to the function. As soon as you see the function call - say y(1, 2) - you know exactly what will happen. (Assuming at least that you are reasonably familiar with the function and what it does - but even if you aren't familiar with it, hopefully it has a name that makes it sufficiently clear.)
The contrast with x is that it reads from external (here global) variables a and b. In other words, it depends on inputs that are not explicitly provided to the function. This makes it much harder to understand what a call to x() will do, because it depends on the value of a and b - which may be assigned quite some distance away in the program. Indeed, perhaps their values can be changed, in different ways, and by other functions - in which case it is impossible to know exactly what x() will do without carefully studying the entirety of the program up until that call. Again, contrast that with y where we need only look at the call site, and nothing else.
While, in some practical situations, it is hard to avoid some sort of "global state", avoiding it as much as possible, and trying to keep the information that a function needs local to it - as in y - is unquestionably better design. It makes the code much easier to understand, and therefore much less likely to have bugs in it.
Within the scope of your second function, a and b refer to the arguments, not the global variables.
var a = 1
var b = 2
function exampleOne () {
console.log("example 1: ", a, b)
}
function exampleTwo (a, b) {
console.log("example 2: ", a, b)
}
exampleOne()
exampleTwo(3, 4)
exampleTwo()
The 3 cases have different purposes, some non exhaustive:
Inside a function:
Only if the variable have to be unloaded after the function call, unless it be returned
function helloworld() {
const words = ['hello', 'world'];
return words.join(' ');
}
As argument:
Every time you want to use an external value which change the result
function hello(name) {
return 'Hello ' + name;
}
From closure:
In others cases:
// inside a lambda
function upperThan(array, n) {
return array.filter(item => item > n);
}
// use a constant
const HELLO = 'Hi';
function sayHello(name) {
return HELLO + ' ' + name;
}
Javascript always pass by value so changing the value of the variable never changes the underlying primitive (String or number).
If you modify variables inside the function that is passed as argument then it does not change the value of orignal variable(Pass by value).
var a = 1;
var b = 2;
function x() {
var c = a + b;
a = c;
console.log(c)
}
function y(a, b) {
var c = a + b;
var a = c;
console.log(c)
}
y(a, b)
console.log(a)
console.log(b)
x()
console.log(a)
console.log(b)
function swap(x,y){
var t=x;
x=y;
y=t;
}
This won't work. when you swap(a,b), variable a and b get copied into the function and whatever happens in that function doesn't affect the real value of a and b. I want something like this:
(function(){
a=1;
b=2;
function swap(){//something}
swap(a,b);
console.log(a) //2
console.log(b) //1
})()
How to do this?
If you are using the latest version of JavaScript (ES2015), then you can use the new language feature called "destructuring". You don't need a function. It looks like this:
let a = 1;
let b = 2;
// swap!
[b, a] = [a, b];
If you want a function, you can do it like this:
function swap(a, b) {
return [b, a]
}
[a, b] = swap(a, b);
Looking at this code, I kind of prefer the function, though it is a bit superfluous. I like how expressive it is. You aren't left puzzling over what the code does.
You can't. Arguments are passed by value, even in the case of objects. It's just that the value passed for them is a reference to the object.
Basically this means that any arguments you receive have no actual connection to the original variables you passed in except that they may share a reference.
Imagine you've written a and b on a piece of paper. In JS, the only way to share those values with a function is to copy them on to a different piece of paper and hand it to the function. So even if that function scratches out a on the new piece of paper and replaces it with b, it doesn't change what you have written on the original piece of paper.
In short, it is not possible to change the value of a variable which was used as an argument for a function.
As mentioned in the answers above, Arguments are only passed by value. If you really need to achieve the swap, you can use the 2 variables algorithm:
var a = 10, b = 20;
a = a + b;
b = a - b;
a = a - b;
console.log (a+" "+b); // 20 10
you can set a variable outside the scope of the function so you can use it inside the function, this is something you can do:
<head>
<script>var x=0, y=1;</script>
</head>
<script>
function swap()
{
var t = x;
x = y;
y = t;
}
</script>
or even this works
<script>
var x=0; y=1;
function swap(id1, id2)
{
var t = x;
x = y;
y = t;
}
console.log(x+" "+y);
</script>
I used this quite a lot and works fine. the x and y can be taken from any where and will work inside a function no problem.
you can also do
function(id1, id2)
{
x=document.getElementById(id1);
y=document.getElementById(id2);
var t = x.value;
x.value = y.value;
y.value = t;
}
function swap(value) {
value.first = value.first + value.second;
value.second = value.first - value.second;
value.first = value.first - value.second;
}
// declared an object named value which has two keys - first and second corresponding to the first and the second values respectively
var value = {
first: 1,
second: 2
}
console.log(value.first, value.second) // prints 1 2
swap(value);
console.log(value.first, value.second); // prints 2 1
When I try to understand plugin codes, I often find these kind of declarations but I don't know exactly what it means.
var a = b,c,d;
This is a syntactic shorthand, and identical to:
var a = b;
var c;
var d;
The first one (a) gets initialized with the value of b, but c and d are uninitialized.
It will define var a = b and then define var c and d