DEV Community

loading...

Discussion on: PHP 8 features I wish also existed in JavaScript

Collapse
devmount profile image
Andreas Author

Thank you for these additions! Can you give examples for #1 and #3 in TypeScript? This article is about native JavaScript since not everyone is using TypeScript in every project.
Of course you can use an object constant, but match is nevertheless a bit more syntactic sugar here and directly assigns the values instead of storing them first 🤷🏻‍♂️

Collapse
mirrorbytes profile image
Bob • Edited

The way you'd used named parameters in JavaScript OR TypeScript is through the use of an object:

JavaScript:

function test ({ a, b, c, d }) {
    ...
}

test({ a: 'test', b: 'test', d: 'test' });
Enter fullscreen mode Exit fullscreen mode

TypeScript:

interface testing {
    a: string;
    b: string;
    c?: string;
    d?: string;
}

function test ({ a, b, c, d }: testing) {
    ...
}

test({ a: 'test', b: 'test', d: 'test' });
Enter fullscreen mode Exit fullscreen mode

The way you'd use optional chaining is actually available in ESNext now:

const country =
  session?.user?.getAddress?.()['country']
  ? session.user.getAddress()['country']
  : null;
Enter fullscreen mode Exit fullscreen mode
Thread Thread
devmount profile image
Andreas Author

Thank you for giving these examples! As I wrote in the article, I know about using object destructuring for named arguments, but I don't like this approach very much here - just doesn't feels like clean coding style to use an object inside the functions parameter definition. I can't think of a reason, why JavaScript doesn't already provide "real" named arguments already...

optional chaining is actually available in ESNext now

Great, didn't know that! 👏🏻

Thread Thread
mirrorbytes profile image
Bob

I agree 100%, however, it would drastically hinder performance as it would almost guaranteed be a runtime check in the engine. That's why I'm hoping either Babel or TypeScript will tackle it in the future to essentially be compiled away into positional arguments.

Thread Thread
valeriavg profile image
Valeria • Edited

Not sure I follow your thought. Typescript performs type checks on compilation only and strips all the types away, so there's never a runtime check.
Update: Oh you mean for chaining arguments? There's zero to none performance loss

Thread Thread
mirrorbytes profile image
Bob

We're discussing named parameters and the performance hit they would be on JavaScript's runtime.

And TypeScript does a whole lot more than type checking nowadays.

Thread Thread
shuckster profile image
Conan

I must chime-in with a report from experience.

Some years ago I worked on a fairly large (~700k lines) JavaScript codebase that implemented a 200-line helper that permitted the following:

function get () {
  var opts = defaults(arguments, {
    byId: null,
    theseItems: '*',
  });
  return [opts.byId, opts.theseItems];
}

get();             // [null, '*']
get(2, 'cats');    // [2, 'cats']
get({ byId: 1 });  // [1, '*']
Enter fullscreen mode Exit fullscreen mode

It was used extensively, including in time-critical places such as during render operations. While there was a performance hit that could be measured with dev-tools, it was nothing compared to the usual day-to-day bottlenecks that were encountered.

The point is to say that sure, worry about performance, but perhaps rest/spread/destructuring isn't the first place you need to look these days.

Collapse
wearypossum4770 profile image
Stephen Smith • Edited

I don't follow the link between "native javascript" and typescript. TS is compiled to JS. I think you can use a Map to achieve the same results with a php match. EDIT
This is a haphazardly written code complete with as close to replicated functionality you would expect from PHP match

class UnhandledMatchError extends Error {
    constructor(value, ...args) {
        super(...args)
        this.name = "UnhandledMatchError"
        this.message = `Unhandled match value of type ${typeof value}`
        Error.captureStackTrace(this, UnhandledMatchError)
    }
}
const match = item => new Map([
    [100, "Super Thin"],
    [300, "Thin"],
    [400, "Normal"],
    [600, "Bold"],
    [900, "Heavy"]
]).get(item) ?? new UnhandledMatchError(item)

console.log(match(100))
>>> Super Thin
console.log(match(102))
>>> UnhandledMatchError: Unhandled match value of type number
Enter fullscreen mode Exit fullscreen mode
Thread Thread
devmount profile image
Andreas Author

As you already said: TS requires a compiler to JS. This article was meant for those writing JS directly.
Cool idea, can you give an example with Map?

Collapse
rsa profile image
Ranieri Althoff

Your example of the switch wouldn't work, you are assigning to a constant variable. I consider declaring without defining an issue, and would rather split the switch to a separate function (e.g. getFontWeight) and create the variable with const fontWeight = getFontWeight(value). It's cleaner and better to test.

Thread Thread
devmount profile image
Andreas Author

My bad, thanks for pointing out 👏🏻 I updated the example code. Totally agree with you about the separate function, nevertheless I just used let to keep things simple.