Reputation: 1517
I have the code that sets a property only if the argument is truthy:
export class Vector {
protected x: number = 0
protected y: number = 0
protected z: number = 0
set(x?: number, y?: number, z?: number) {
this.x = x ? x : this.x
this.y = y ? y : this.y
this.z = z ? z : this.z
}
}
However, I don't want to provide a fallback value of the current value. Ideally, I want to just do nothing if the value is falsy, like this:
if (x) {
this.x = x
}
if (x) {
this.y = y
}
if (z) {
this.z = z
}
… but I don't want to write it like this, it is not cool. I'm looking for something like this:
this.x = x ? x
this.y = y ? y
this.z = z ? z
Is there any similar syntax that does what I want?
Upvotes: 2
Views: 1103
Reputation: 9855
Aside from other answers, you have three more options:
Use if
one-liner:
if (x) this.x = x
if (y) this.y = y
if (z) this.z = z
Use ??
operator (it wasn't available in 2018, when the question was asked):
this.x = x ?? this.x
this.y = y ?? this.y
this.z = z ?? this.z
Use default values for optional parameters:
export class Vector {
protected x: number = 0
protected y: number = 0
protected z: number = 0
set(x = this.x, y = this.y, z = this.z) {
this.x = x
this.y = y
this.z = z
}
}
Upvotes: 0
Reputation: 750
Usually x && this.x=x
would be the shortest syntax to get this done.
However x, y and z are all numbers. It's a bit dangerous to use this short-hand syntax for numbers. Consider the case where set is called with x=0. 0 && this.x=x
would not execute this.x as 0 is falsey in Javascript. From reading your code this does not seem like what you want to achieve, instead you want to skip setting this.x in the case x is undefined.
In that case, I suggest the following code:
set(x?: number , y? : number , z? : number){
typeof x === 'number' && (this.x = x);
typeof y === 'number' && (this.y = y);
typeof z === 'number' && (this.z = z);
}
That way your set
-function will support sending 0 as an argument, which it currently does not.
Upvotes: 4
Reputation: 2828
A clean way to write your method is
set(x?: number , y? : number , z? : number){
this.x = x || this.x;
this.y = y || this.y;
this.z = z || this.z;
}
An other way is
set(x?: number , y? : number , z? : number){
x && this.x = x;
y && this.y = y;
z && this.z = z;
}
But, as @Lars Holdaas already mentioned, this will not support the falsy values (like 0
or ""
).
The generic way to solve this is by writing a validation or filter function to tell if the value is
actually truly for that parameter or not.
// returns `true` if x is a number
const n = x => typeof n === 'number';
set(x?: number , y? : number , z? : number){
n(x) && this.x = x;
n(y) && this.y = y;
n(z) && this.z = z;
}
Hope this helps :)
Upvotes: 2