How can I check if 2 variables with the same value are the same variable?
For example in the below code I created 2 variables with the same values and i pass:
function check_var(v){
// Check if "v" (string) came from a or b
}
let a = "string";
let b = "string";
check_var(b);
I able to install v8 engine locally and change the the source code, but i am looking for more easy way to do it.
One way to do it is if I had a method in javascript that returns a unique value for each variable based on the variable name.
One more way to solve the problem is by logging all the javascript actions, by doing that i could see after the code executed if var a is the var that got into the check_var function.
In general you cannot, JavaScript doesn't have a universal identity equality operator.
Strings, numbers and some other simple values can only be compared by value. Tho objects, including arrays are compared by identity.
const a = [1]
const b = [1]
a===b // false
If this is important you could box the value
const a = { value: 'string' }
const b = { value: 'string' }
const c = a
a.value === b.value // true
a === b // false
a === c // true
Related
let a = 7;
a = 3;
console.log(a); // output 3
In this case, the value 7 is still inside a memory? I was reading that all primitive data types are immutable.
The value of a is kept in memory, until garbage collection eventually recycles it. What the docs mean by immutable is that you can't directly alter the primative (in this case the integer 7). You can only replace the value.
There are examples on the docs but this is another one
let a = 1;
a.toString() // a is still 1, it cannot be mutated
However, we can assign this to another variable
let a = 1;
let b = a.toString() // b is string "1" and a remains as the integer 1
Or we can replace the value
let a = 1;
a = 10; // a is 10
Short answer: no.
Immutable is about the behaviour of the value, not about what happens when it's no longer being references: you cannot change an immutable value, you have to instead reassign your variable if you want it to point to a new value.
let b = 3;
let a = b; // the variable "a" points to the primitive value 3
b = 7; // the variable "a" still points to the primitive value 3
a = 7; // and now it points to a _different_ value. 7, in this case.
This is in contrast to things like arrays or objects, which you can change as much as you like without needing to reassign:
const obj = {};
const a = obj;
obj.cat = `meow`;
console.log(a); // this will show that "a" is { cat: "meow" }
We just changed the content of the value that "a" points to, without any reassignments.
This question already has answers here:
How do I test for an empty JavaScript object?
(48 answers)
Closed 7 months ago.
I'm learing JavaScript. I cannot grasp the idea of an empty object. As I understand, there are situations when I need to check a variable whether it holds an object and has a value.
So far, I know that a variable can be undefined.
var car; // the value is undefined, as well as the type (which is it? number, array, etc.)
I also know, that everything that has a value, is true:
var car = "Opel";
Boolean(car); // true
And anything without a value is false:
var car = ""; // typeof string, but it is empty, so
Boolean(car); // false
Boolean(null); // false
So why doesn't it work the same way with arrays and objects? Why is all of this true? Shouldn't empty arrays and objects return false?
var car = {make: "Opel", year: 2015};
Boolean(car); // true
car = {};
Boolean(car); // true
car = ["BMW", "Opel"];
Boolean(car); // true
car = [];
Boolean(car); // true
Now I see that there are methods, that can be applied to check an object's length, I just haven't reached that part yet.
I'm learning at W3Schools website and this bit just got me puzzled:
But you cannot test if an object is null, because this will throw an error if the object is undefined:
Incorrect:
if (myObj === null)
To solve this problem, you must test if an object is not null, and not undefined.
But this can still throw an error:
Incorrect:
if (myObj !== null && typeof myObj !== "undefined")
Because of this, you must test for not undefined before you can test for not null:
Correct:
if (typeof myObj !== "undefined" && myObj !== null)
I still cannot understand the last line here.
Checking if an object is empty:
Object.keys(yourObject).length
var car = {};
var isEmpty = Object.entries(car).length > 0; //false
var car = {make: "Opel", year: 2015};
var isEmpty = Object.entries(car).length > 0; //true
This should solve your problem, if your curious about the utility function Object.entries you can look on mdn
I also know, that everything that has a value, is true
I wouldn't say that. All the examples given are values, even undefined and null are predefined values in JavaScript.
Shouldn't empty arrays and objects return false?
It is like that by specification. And that is really the answer to your question. It is a choice made by the designers of the language.
You could find some logic in it though. In JavaScript, values representing objects (and so also arrays) are references. These references are memory addresses/pointers, and although you cannot find out what exactly those addresses are, these are non-zero, even when an object has no properties.
Note that your example objects ({} and []) still have some non-enumerable properties, such a __proto__ and (for array) length, so they are not really as empty as you think.
The most empty object you can create, is: Object.create(null)
You can check wheather a object is empty or not in this simple way.
function objectLength( object ) {
return Object.keys(object).length;
}
if(objectLength(yourObject) == 0){
//object is empty
}else{
//object not empty
}
Checking if an object is empty:
Reflect.ownKeys(car).length
Returns an array with one element when a Symbol is used as the key:
let key = Symbol('vin')
let car = { [key]: 'honda' }
Reflect.ownKeys(car).length // => 1
Whereas Object.keys returns an array with zero elements in this case:
let key = Symbol('vin')
let car = { [key]: 'honda' }
Object.keys(car).length // => 0
I would always use typeof myvar !== 'undefined' and checks for content myvar !== ''
This would always would have a clear result.
There are concepts which are Truthy and Falsy values in JavaScript.
I highly recommend you to read MDN documents about this issue.
All values are truthy unless they are defined as falsy (i.e., except for false, 0, -0, 0n, "", null, undefined, and NaN).
Truthy values
Falsy values
No, they should not be false.
All objects are 'truthy', in that they return true when evaluated as a Boolean. In Javascript, all arrays are objects (try console.log(typeof [])), so they also return true, regardless of whether or not they are empty.
To check if any array is empty:
if (MYARRAY.length === 0) {
// console.log(true);
}
To check if an object is empty:
if (Object.keys(MYOBJECT).length === 0) {
// console.log(true);
}
You can use
if ($('#element').is(':empty')){
//do something
}
OR
function isEmpty( el ){
return !$.trim(el.html())
}
if (isEmpty($('#element'))) {
// do something
}
Here are some examples: http://api.jquery.com/is/
But if you need it in JavaScript:
if( typeof foo !== 'undefined' ) {
// foo could get resolved and it's defined
}
You can simply use typeof
The following TypeScript:
enum PrimaryColors { Red, Green, Blue };
Produces the following JavaScript:
var PrimaryColors;
(function (PrimaryColors) {
PrimaryColors[PrimaryColors["Red"] = 0] = "Red";
PrimaryColors[PrimaryColors["Green"] = 1] = "Green";
PrimaryColors[PrimaryColors["Blue"] = 2] = "Blue";
})(PrimaryColors || (PrimaryColors = {}));
;
I am embarrassed to admit that I don't understand what the JavaScript is doing.
The function in parentheses is assigning string values using another assignment as the index/key. I have not seen anything like this before.
And what is the purpose of the (PrimaryColors || (PrimaryColors = {}) following the function?
If the answer is to learn JavaScript properly, I will readily accept it, provided it comes with a suggested source that clearly explains what I am seeing here.
I believe:
PrimaryColors[PrimaryColors["Red"] = 0] = "Red";
is equivalent to:
PrimaryColors[0] = "Red";
PrimaryColors["Red"] = 0;
See this reference.
The expression x = 7 is an example of the first type. This expression
uses the = operator to assign the value seven to the variable x. The
expression itself evaluates to seven.
For example:
console.log((x = 7));
outputs:
7
Similarly:
var x = {};
console.log((x["hi"] = 7));
Also outputs 7.
As for the second thing, PrimaryColors is initially undefined.
var x;
console.log(x); // undefined
In a boolean context, undefined evaluates to false:
console.log(!undefined); // true
console.log(!!undefined); // false
Sanity check:
console.log((!undefined) === true); // true
console.log((!!undefined) === false); // true
console.log(undefined === false); // false
This is a common usage of short circuiting. Because PrimaryColors is initially undefined (false), it will pass {} to the function.
PrimaryColors || (PrimaryColors = {})
Maybe this will help.
(function() {})();
This is an 'immediately executing function'. It defines a function as an expression, and then invokes it.
var x = y || y = {};
If a common pattern for initializing something to a default value. If y does not have a value, the 1st part of the or-statement is false, so it executes the 2nd part, which assigns a value to y. The value of that 2nd expression is the new value of y. So x becomes that value of y -- which is the new value if it wasn't already defined.
x[y] = z;
Objects in JS are associative arrays. In other words, string-object pairs, like IDictionary(string,object). This expression is setting the key with value y to the value of z, in the dictionary x;
x[x["a"] = 0] = "a";
So, same thing here, but with a nested expression, which is:
x["a"] = 0;
So that just sets the value of key "a". Nothing fancy. But this is also an expression, whose value is 0. So substitute that in the original expression:
x[0] = "a";
Keys need to be strings, so it's actually the same thing as:
x["0"] = "a";
Which just sets yet another key in the dictionary. Result is that these statements are true:
x["0"] === "a";
x["a"] === 0;
I found this question because I was wondering why use an IIFE at all when you can just init the var with {} right off. The previous answers don’t cover it, but I’ve found my answer in the TypeScript Deep Dive.
The thing is, enums can be split into multiple files. You just have to explicitly initialize the first member of second, third, etc. enums, so this:
enum Colors {
Red,
Green,
Blue
}
enum Colors {
Cyan = 3,
Magenta,
Lime
}
transpiles to this:
var Colors;
(function (Colors) {
Colors[Colors["Red"] = 0] = "Red";
Colors[Colors["Green"] = 1] = "Green";
Colors[Colors["Blue"] = 2] = "Blue";
})(Colors || (Colors = {}));
var Colors;
(function (Colors) {
Colors[Colors["Cyan"] = 3] = "Cyan";
Colors[Colors["Magenta"] = 4] = "Magenta";
Colors[Colors["Lime"] = 5] = "Lime";
})(Colors || (Colors = {}));
As you probably know, redeclaring a variable within the same scope is harmless, but reinitialization is not.
I think they could probably just go:
var Colors;
Colors || (Colors = {});
Colors[Colors["Cyan"] = 3] = "Cyan";
// ...
and skip the closure, but maybe I’m still missing something.
It is used to create an associated map (in other words an object) where you will retrieve the 'name' of the enum value by using the index as key and vice versa. In other words: PrimaryColors["Red"] (or PrimaryColors.Red using dot notation) will yield 0. PrimaryColors[0] (dot notation would be invalid here) will yield "Red".
Understanding the implementation is actually not that hard if we consider three concepts:
The assignment of values to existing variables in javascript evaluates to a value (so it's an expression rather than a statement in spirit)
Object attributes (keys) can be accessed via brackets given their key
Object attributes need to be of type string or Symbol but other values will be propagated to a string if possible.
Therefore:
PrimaryColors[PrimaryColors["Red"] = 0] = "Red";
is equivalent to
const valueToBeUsedAsIndex = PrimaryColors.Red = 0; // assignment evaluates to 0, i. e. valueToBeUsedAsIndex has value 0
PrimaryColors[valueToBeUsedAsIndex] = "Red"; // PrimaryColors[0] is "Red". Technically this assignment yields a value too ("Red" in this particular case) but the value is discarded as it's not needed anymore
// at this point PrimaryColors looks like this: { Red: 0, "0": "Red" }
Lots of great answers here and thank you all, but I would like to add more for simplicity and for my personal reference, and for others who have the same learning structure in breaking things down to the last bit, I will be skipping the Immediately-invoked Function Expressions (IIFE) ill image we all already know that part
now let me break it step by step
PrimaryColors = {} // right now this is an empty object
PrimaryColors[PrimaryColors["Red"]=0] = 'Red'
the most important part here is many don't know that when u set a value to an object
you get a returned value
like below
pp = {}
dd = pp['red']=0
0 // as you can see here the result of the assignment is returned
//now dd is assigned this returned value
// this is the same thing going on here.
> dd
0
we are setting the returned value as the key which is 0 which the javascript hashing algorithm converts to a string and returns as a string.
I hope everyone understands.
Very simple example:
var a = { id: 5 };
var b = { id: 6 };
var c = { id: 7 };
var arr = [a, b, c];
Now i have a function:
function remove(startIndex) {
// set objects to null from startIndex in array
}
If i try this:
arr[0] = null;
then i have:
arr[0] == null // true
a == null // false (i need true)
So, my question, how could i access to object throw any collection (array or object) and change it?
I don't want to write something like this:
function remove(startIndex) {
if(startIndex == 0) {
a = null;
b = null;
c = null;
}
if(startIndex == 1) {
b = null;
c = null;
}
if(startIndex == 2) {
c = null;
}
}
much easier to write like this (but it doesn't work):
function remove(startIndex) {
for(var i = startIndex; i<arr.length; i++) arr[i] = null;
}
I don't know exactly what you're aiming with this code you're writing, but here's how Javascript works:
Every time you instantiate a variable with a value, say an object like { id: 10 }. That object is stored in memory and a reference is returned back to your variable, say you name it a.
Now, if you say var b = a;, the same reference is now passed on to variable b. Now Javascript runtime knows you have two variables referencing the object { id: 10 }.
You now no longer want to keep the variable b, so you write b = null;. You think the object is deleted, but the Javascript runtime knows the object { id: 10 } has one reference -- i.e. the variable a -- referencing it. So it won't remove { id: 10 } from memory.
However, if you also write a = null;, then there are Zero references, and the Javascript runtime's Garbage Collector will eventually get to removing the object from memory.
All this was to get you to understand that without further housekeeping, you will not be able to achieve what you're hoping to do.
If you really want a, b, c to be null, you will have to write some code that explicitly sets their value to null too. Like a = arr[0]; b = arr[1]; c = arr[2]; whenever the array is changed. You can eval the statements and do some string templating to not write the variables by hand etc., and make a loop out of that, but that's not worth it if you only have three variables.
Hope this helps.
JavaScript doesn't have pointers, so to achieve what you want in the original way will not work.
Other than arr[0] = null, you can try setting a to null directly as well.
This question already has answers here:
Is there a better way to do optional function parameters in JavaScript? [duplicate]
(28 answers)
Closed 3 years ago.
Can I declare default parameter like
function myFunc( a, b=0)
{
// b is my optional parameter
}
in JavaScript?
With ES6: This is now part of the language:
function myFunc(a, b = 0) {
// function body
}
Please keep in mind that ES6 checks the values against undefined and not against truthy-ness (so only real undefined values get the default value - falsy values like null will not default).
With ES5:
function myFunc(a,b) {
b = b || 0;
// b will be set either to b or to 0.
}
This works as long as all values you explicitly pass in are truthy.
Values that are not truthy as per MiniGod's comment: null, undefined, 0, false, ''
It's pretty common to see JavaScript libraries to do a bunch of checks on optional inputs before the function actually starts.
Update
With ES6, this is possible in exactly the manner you have described; a detailed description can be found in the documentation.
Old answer
Default parameters in JavaScript can be implemented in mainly two ways:
function myfunc(a, b)
{
// use this if you specifically want to know if b was passed
if (b === undefined) {
// b was not passed
}
// use this if you know that a truthy value comparison will be enough
if (b) {
// b was passed and has truthy value
} else {
// b was not passed or has falsy value
}
// use this to set b to a default value (using truthy comparison)
b = b || "default value";
}
The expression b || "default value" evaluates the value AND existence of b and returns the value of "default value" if b either doesn't exist or is falsy.
Alternative declaration:
function myfunc(a)
{
var b;
// use this to determine whether b was passed or not
if (arguments.length == 1) {
// b was not passed
} else {
b = arguments[1]; // take second argument
}
}
The special "array" arguments is available inside the function; it contains all the arguments, starting from index 0 to N - 1 (where N is the number of arguments passed).
This is typically used to support an unknown number of optional parameters (of the same type); however, stating the expected arguments is preferred!
Further considerations
Although undefined is not writable since ES5, some browsers are known to not enforce this. There are two alternatives you could use if you're worried about this:
b === void 0;
typeof b === 'undefined'; // also works for undeclared variables