2

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?

6
  • 3
    a ? a : b is equivalent to a || b (unless a expression has side effects). Commented Aug 30, 2018 at 11:10
  • You could also remove the set method and make your properties public and set them when they need to be different from default Commented Aug 30, 2018 at 11:11
  • Thank you for a comment!!! Is it possible to erase ":b"? I want to do nothing if there wan no a. I don't want to do b. Commented Aug 30, 2018 at 11:12
  • What @raina77ow means is usage like this: this.x = x || this.x Commented Aug 30, 2018 at 11:13
  • 2
    x && this.x = x; y && this.y = y; etc. Commented Aug 30, 2018 at 11:17

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

7 Comments

OH!!! You are so smart to notice that 0 is false!!! Very good study for me.But VSCODE give me error.";" is required(T_T)
Can you see which line you're required to add ;?
I add message to you on the question!
Oh!!! No error!!!! I think this is the coolest way!!!!! Thank you so much , handsome man!!!
The OP's message was edited out of the question. The code that produced the error was: typeof x === 'number' && this.x = x; (screenshot of the error: i.sstatic.net/Z2ryk.png)
|
2

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 :)

Comments

0

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
        }
    }
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.