I need helps with convert the statement below to ES5 syntax. What will it be in ES5?
const { a, b, c = “foo” } = this.props;
I suggest to use an explicit check if property c exists in the given object or not. If not given, then use the default value.
var a = this.props.a,
b = this.props.b,
c = this.props.c === undefined ? 'foo' : this.props.c;
The otherwise used pattern
c = this.props.c || 'foo';
does not work for given falsy value like zero.
Why do you need a check with undefined (kudos to loganfsmyth for mention this problem in comments)?
Because undefined is the value for the check for default parameters in a function in ES6.
const f = (c = 'foo') => console.log(c);
f(); // 'foo'
f(undefined); // 'foo'
f(0) // 0
var
a=this.props.a,
b=this.props.b,
c=this.props.c||"foo";
Object destructuring trys to find properties with the same name in the object, so
{prop}=obj
equals:
prop=obj.prop;
The default parameter can be easily achieved with an Or operator:
prop=obj.prop || default;
or if you want to count falsys as a prop, itll be:
prop=("prop" in obj)?obj["prop"]:default;
I believe it would be :
var a = this.props.a,
b = this.props.b,
c = this.props.c || "foo"
At least I hope, otherwise it'll be raining downvotes
The easiest way to achieve this would be:
var a = this.props.a,
b = this.props.b,
c = this.props.c===undefined?"foo":this.props.c
But the better way would be to just use the this.props object instead of storing it in local variables.
Related
I know that I can test for a JavaScript variable and then define it if it is undefined, but is there not some way of saying
var setVariable = localStorage.getItem('value') || 0;
seems like a much clearer way, and I'm pretty sure I've seen this in other languages.
Yes, it can do that, but strictly speaking that will assign the default value if the retrieved value is falsey, as opposed to truly undefined. It would therefore not only match undefined but also null, false, 0, NaN, "" (but not "0").
If you want to set to default only if the variable is strictly undefined then the safest way is to write:
var x = (typeof x === 'undefined') ? your_default_value : x;
On newer browsers it's actually safe to write:
var x = (x === undefined) ? your_default_value : x;
but be aware that it is possible to subvert this on older browsers where it was permitted to declare a variable named undefined that has a defined value, causing the test to fail.
Logical nullish assignment, ES2020+ solution
New operators are currently being added to the browsers, ??=, ||=, and &&=. This post will focus on ??=.
This checks if left side is undefined or null, short-circuiting if already defined. If not, the right-side is assigned to the left-side variable.
Comparing Methods
// Using ??=
name ??= "Dave"
// Previously, ES2020
name = name ?? "Dave"
// or
if (typeof name === "undefined" || name === null) {
name = true
}
// Before that (not equivalent, but commonly used)
name = name || "Dave" // Now: name ||= "Dave"
Basic Examples
let a // undefined
let b = null
let c = false
a ??= true // true
b ??= true // true
c ??= true // false
Object/Array Examples
let x = ["foo"]
let y = { foo: "fizz" }
x[0] ??= "bar" // "foo"
x[1] ??= "bar" // "bar"
y.foo ??= "buzz" // "fizz"
y.bar ??= "buzz" // "buzz"
x // Array [ "foo", "bar" ]
y // Object { foo: "fizz", bar: "buzz" }
??= Browser Support Oct 2022 - 93%
??= Mozilla Documentation
||= Mozilla Documentation
&&= Mozilla Documentation
The 2018 ES6 answer is:
return Object.is(x, undefined) ? y : x;
If variable x is undefined, return variable y... otherwise if variable x is defined, return variable x.
ES2020 Answer
With the Nullish Coalescing Operator, you can set a default value if value is null or undefined.
const setVariable = localStorage.getItem('value') ?? 0;
However, you should be aware that the nullish coalescing operator does not return the default value for other types of falsy value such as 0 and ''.
However, do take note of the browser support. You may need to use a JavaScript compiler like Babel to convert it into something more backward compatible. If you are using Node.js, it has been supported since version 14.
I needed to "set a variable if undefined" in several places. I created a function using #Alnitak answer. Hopefully it helps someone.
function setDefaultVal(value, defaultValue){
return (value === undefined) ? defaultValue : value;
}
Usage:
hasPoints = setDefaultVal(this.hasPoints, true);
It seems more logical to check typeof instead of undefined? I assume you expect a number as you set the var to 0 when undefined:
var getVariable = localStorage.getItem('value');
var setVariable = (typeof getVariable == 'number') ? getVariable : 0;
In this case if getVariable is not a number (string, object, whatever), setVariable is set to 0
In our days you actually can do your approach with JS:
// Your variable is null
// or '', 0, false, undefined
let x = null;
// Set default value
x = x || 'default value';
console.log(x); // default value
So your example WILL work:
const setVariable = localStorage.getItem('value') || 0;
You can use any of below ways.
let x;
let y = 4;
x || (x = y)
in ES12 or after
let x;
let y = 4;
x ||= y;
If you're a FP (functional programming) fan, Ramda has a neat helper function for this called defaultTo :
usage:
const result = defaultTo(30)(value)
It's more useful when dealing with undefined boolean values:
const result2 = defaultTo(false)(dashboard.someValue)
var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;
Ran into this scenario today as well where I didn't want zero to be overwritten for several values. We have a file with some common utility methods for scenarios like this. Here's what I added to handle the scenario and be flexible.
function getIfNotSet(value, newValue, overwriteNull, overwriteZero) {
if (typeof (value) === 'undefined') {
return newValue;
} else if (value === null && overwriteNull === true) {
return newValue;
} else if (value === 0 && overwriteZero === true) {
return newValue;
} else {
return value;
}
}
It can then be called with the last two parameters being optional if I want to only set for undefined values or also overwrite null or 0 values. Here's an example of a call to it that will set the ID to -1 if the ID is undefined or null, but wont overwrite a 0 value.
data.ID = Util.getIfNotSet(data.ID, -1, true);
Works even if the default value is a boolean value:
var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );
It seems to me, that for current javascript implementations,
var [result='default']=[possiblyUndefinedValue]
is a nice way to do this (using object deconstruction).
var A = $(this).attr("id") //result is a string
var B = $(this).attr("id") //result is another string from a different id
var C = {
A: B //I want to use A as Property and B as Value
};
when console.log(C) is made, JS console says that A is undefined. Why is this so?
//How can I use A as Property and B as Value as Object inside variable C then for Javascript and jQuery? //Thanks.
Use brackets in property:
var C = { [A]: B };
You can do that using the brackets syntax:
var C = {};
C[A] = B;
Or you can use the "Computed Property Name" ES6 feature:
var C = { [A]: B };
If I understood you correctly you want to achieve something like this:
var a = 'something';
var b = 'else';
// example var c = { something: "else" };
if so, then it's super easy without advanced es6 experimental feats ;)
just (I'm using es6 template literals - but you can do with normal string concat):
var c = JSON.parse(`{"${a}":"${b}"}`);
I was reading javascript questions where i found this piece of code
var a={},
b={key:'b'},
c={key:'c'};
a[b] = 123;
a[c] = 456;
console.log(a[b]); // o/p - 456
can anybody make me understand this code why and how it is printing 456?
And I think we can use dot i.e a.b = 123 and string a['b'] = 123 approach to add property to an object.
Both b and c resolve to the same string ([object Object]). Hence you are overwriting the same key.
And I think we can use dot i.e a.b = 123 and string a['b'] = 123
approach to add property to an object.
Yes you can, but a['b'] is very different from a[b]. The first one resolves to a key with a string value just as it shows ('b'), where as the other one will depend on the stringified value of the variable b (in this case is [object Object]).
For really using the content of the object, you may use the stringified version.
var a = {},
b = { key: 'b' },
c = { key: 'c' };
a[JSON.stringify(b)] = 123;
a[JSON.stringify(c)] = 456;
console.log(a[JSON.stringify(b)]);
I have been reviewing other people's code and while ES2015 on the whole is taking some getting use to, however, I keep on getting stuck with Destructuring.
Previously, In Javascript, the Curly Brackets {} were either used for blocks or objects. e.g.
// Curly Brackets Block
If () {
...
}
// Curly Brackets in Obj
var obj = {
a : 1,
...
}
However, in destructuring, we see again and again the following syntax:
let a = ({ a, b }) => {
}
My question, is the arguments container an actual object or just a block?
Please explain whether the following be the same as the code above:
let a = ( a, b ) => {
}
EDIT: My understanding (so far) from reading Axel Rauschmayers article on Destruturing is that we are merely mapping the props. into a new Obj always? I.e:
let a = { first : a, second : b } = AnObj;
===
a.a === AnObj.first;
a.b === AnObj.second;
Is the above correct? Is an obj always instantiated? However, that doesn't make sense as in the above function, the object thus created for the props would be an anonymous object, right?
Many thanks,
No, the curly braces in destructuring do form neither a block nor an object literal.
They definitely are not a block because they are not a statement (and don't contain a statement list), they are an expression like an object literal. In fact they even do have the same syntax as an object literal, the only difference is that they are in the position of an assignment target (left hand side of an assignment operator) or a function parameter.
Is let a = ({ a, b }) => {…} the same as let a = ( a, b ) => {…}?
No, really not. Both parameter lists do declare variables a and b for the function scope, but the first function expects an object with properties .a and .b while the second function expects two arguments.
My understanding is that we are merely mapping the properties into a new obj?
No. There is no new object created/instantiated. There is only the object that you pass in (the right hand side). And it is destructured - "pulled apart" - into pieces that are then assigned to the various sub-targets (variables, property references).
To write
a.b = anObj.first;
a.c = anObj.second;
with a destructuring assignment you'd use
({first: a.b, second: a.c}) = anObj;
(the parenthesis are necessary to distinguish the expression from a block).
The more common use case is for variable initialisations however. You can shorten
let b = anObj.first,
c = anObj.second;
to
let {first: b, second: c} = anObj;
And also there's a shorthand when the variable has the same name as the property, so
let first = anObj.first,
second = anObj.second;
is equivalent to
let {first, second} = anObj;
Is let a = { first : a, second : b } = anObj; correct?
No, that doesn't make much sense. It would desugar to
let a;
a = anObj.first;
b = anObj.second;
a = anObj;
It is for destructuring:
var obj = {a: 1, b: 2},
add = ({a, b}) => a + b;
console.log(add(obj)); //3
So basically to the statements inside the function it would appear there are 2 arguments, but when you call it you only pass an object.
I found this example in a book:
// Create _callbacks object, unless it already exists
var calls = this._callbacks || (this._callbacks = {});
I simplified it so that I did not have to use a special object scope:
var a = b || (b = "Hello!");
When b is defined, it works. When b is not defined, it does not work and throws a ReferenceError.
ReferenceError: b is not defined
Did I do anything wrong? Thank you!
When performing a property lookup like this._callback, if the _callbacks property does not exist for this you will get undefined. However if you just do a lookup on a bare name like b, you will get a reference error if b does not exist.
One option here is to use a ternary with the typeof operator, which will return "undefined" if the operand is a variable that has not been defined. For example:
var a = typeof b !== "undefined" ? b : (b = "Hello!");
It should work in this form:
var b, a = b || (b = "Hello!", b);
// ^ assign b
// ^ () and , for continuation
// ^ return the new value of b
//=> result: a === b = "Hello!"