Skip to content

Quick Guide from Perl to Javascript/ES6/Typescript

Long, Interpolated Strings

Perl:

my $str = qq{
    This is a long
    string in $language
};

JS:

const language = 'javascript';
const str = `
    This is a long
    string in ${language}
`;

Array push, pop, shift, unshift

Perl:

my @somearr;
push @somearr, ( 'something', 'foobar' );

my @another = ( 'quz', 'qar' );
push @another, @somearr;

shift @somearr;
pop @somearr;
unshift @somearr, 'more stuff';

# concat arrays:
my @newarr = ( @somearr, @another );

JS:

const somearr = [];
somearr.push('something','foobar');

const another = [ 'quz', 'qar' ];
somearr.push( ...another );

somearr.shift();
somearr.pop();
somearr.unshift('more stuff');

// concat arrays:
const newarr = somearr.concat(another);

Array iteration

Perl:

foreach my $it ( @someArray ) {
    say $it;
}

JS:

for( const it of someArray ) {
    console.log(it);
}

// or:
someArray.forEach( it => console.log(it) );

// or even shorter:
someArray.forEach( console.log );

Get a hash value

Perl:

    my %hash = ( aa => 11, "long key" => 22, nested => { foo => 33 } );
    print $hash{aa};
    print $hash{'long key'};
    print $hash{nested}{foo};

    my $hashref = { aa => 11, "long key" => 22, nested => { foo => 33 } };
    print $hashref->{aa};
    print $hashref->{'long key'};
    print $hashref->{nested}{foo};

JS:

    const obj = { aa: 11, 'long key': 22, nested: { foo: 33 } };
    console.log( obj.aa );
    console.log( obj['aa'] );
    console.log( obj['long key'] );
    console.log( obj.nested.foo );
    console.log( obj['nested']['foo'] );

Hash keys iteration

Perl:

for my $key ( keys %someHash ) {
    ...
}

JS:

for( const key of Object.keys(someHash) ) {
    ...
}

// or

Object.keys(someHash).forEach( key => { ... } );

Hash values iteration

Perl:

my %someHash = ( aa => 11, bb => 22 );

for my $val ( values %someHash ) {
    // 11, 22
}

JS:

for( const val of Object.values(someHash) ) {
    ...
}

// or

Object.keys(someHash).forEach( key => { ... } );

Key-value hash iteration

Perl:

while( my ( $key, $val ) = each %someHash ) {
    ...
}

JS:

for( const [key,val] of Object.entries(someHash) ) {
    ...
}

Expand and merge array

Perl:

my @arrayMerged = ( 'aa', 'bb', @arrayA, @arrayB );

JS:

const arrayMerged = [ 'aa', 'bb', ...arrayA, ...arrayB ];

// or

const arrayMerged = [ 'aa', 'bb' ].concat(arrayA).concat(arrayB);

Merge hashes

Perl:

my %hashMerged = ( aa => 11, bb => 22, %hashA, %hashB );

JS:

const hashMerged = { aa: 11, bb: 22, ...hashA, ...hashB };

// or:

const hashMerged = Object.assign({ aa: 11, bb: 22 }, hashA, hashB );

// careful: Object.assign() changes the hash in place

const hashMerged = { aa: 11, bb: 22 };
Objecy.assign( hashMerged, hashA, hashB );  // hashMerged is changed in place

Delete a Hash key, and save value

Perl:

my $val = delete $someHash{ 'someKey' };

JS:

const val = someHash[someKey];
delete someHash[someKey]; // delete does not return a value

Create hash from variable keys and values

Perl:

my $key1 = 'aa';
my $value1 = 11;
my %someHash = { $key1 => $value1, $key2 => $value2 };

JS:

const key1 = 'aa';
const value1 = 11;
const someHash = { [key1]: value1, [key2]: value2 };

Map

Perl:

my $newArr = map { $_ + 1 } @someArr;

JS:

const newArr = someArr.map( it => it + 1 );

// or:

const newArr = someArr.map( it => {
    return it + 1
});

Grep / Filter

Perl:

my @filtered = grep { $_ eq 'foo' } @someArr;

JS:

const filtered = someArr.filter( it => it === 'foo' );

Sorting alphabetically

Perl:

my @sortedAscending = sort { lc $a cmp lc $b } @unsortedArr;
my @sortedDescending = sort { lc $b cmp lc $a } @unsortedArr;

JS:

const sortedAscending = unsortedArr.sort((a = '', b = '') =>
    a.toUpperCase().localeCompare(b.toUpperCase())
);

const sortedDescending = unsortedArr.sort((a = '', b = '') =>
    b.toUpperCase().localeCompare(a.toUpperCase())
);

Convert Array to hash

Perl:

my %someHash = map { $_ => 1 } @someArray;

JS:

const someHash = someArray.reduce( (obj, val) => {
    obj[val] = 1;
    return obj;
}, {});

// shorter notation with comma:

const someHash = someArray.reduce( (obj, val) => (obj[val] = 1, obj) );

Deconstruct Array

Perl:

my @someArray = ( 11, 22, 33, 44 );
my ( $first, $second, @rest ) = @someArray;

JS:

const someArr = [ 11, 22, 33, 44 ];
const [ first, second, ...rest ] = someArr;

Deconstruct Hash

Perl:

my %someHash = ( aa => 11, bb => 22 );
my ( $aa, $bb ) = @{ \%someHash }{ qw( aa bb ) };

JS:

const someHash = { aa: 11, bb: 22, cc: 33, dd: 44 };
const { aa, bb } = someHash;

// you can also get the rest, cant easily do this in Perl
const { aa, bb, ...otherKeysInHash } = someHash;

Is value in array?

Perl:

if( 'foo' ~~ @someArr ) { ... }

JS:

if( someArr.includes('foo') ) { ... }
if( someArr.indexOf('foo') > -1 ) { ... }

Var is defined?

Perl:

if( defined $myvar ) {
    ...
}

JS:

if( myvar !== undefined ) {
    ...
}

Var is null/falsy/undefined?

Perl:

if( ! $myvar ) {
    ...
}

JS:

if( ! myvar ) {
    ...
}

Var is just null/undefined?

Perl:

if( ! length $myvar ) {   # 0 and 1 are ok
    ...
}

JS:

if( myvar != null ) {  // true, false, 0 and 1 are ok
    ...
}

OR undefined value

Perl:

my $val = $someVar // 'some default';

JS (ES2020/TS 3.7+):

const val = someVar ?? 'some default';

Subs/Functions

Perl:

sub myfunc {
    my ( $x ) = @_;
    $x //= 10;  # a default value
    return $x + $x;
}

JS:

function myfunc(x = 10) {
    return x + x;
}

Subs/Functions in vars

Perl:

my $double = sub {
    my ( $v ) = @_;
    return $v * 2;
};

$double->(1234);

JS:

const double = v => v * 2;
double(1234);

// longform:

const double = v => {
    return v * 2;
};
double(1234);

Get all function args as array

Perl:

sub myfunc {
    for my $arg ( @_ ) {
    }
}

JS:

function myfunc(...args) {
    for( const arg of args ) {
    }
}

Check if null/undef before calling method

Perl:

$obj->deploy if $obj;

JS (ES2020 or TS 3.7+):

obj?.deploy();

Check if member function exists:

Perl:

if( $obj->can('deploy') ) {
    $obj->deploy;
}

JS:

obj?.deploy();  // TS or ES2020
// or
if( obj.deploy ) {
    obj.deploy()
}

Simple Regular expression test

Perl:

if( $someStr =~ /foo/i ) { ... }

JS:

if( /foo/i.test(someStr) ) { ... }

Regular expression substitution

Perl:

$someStr =~ s/aaa (\d+)/bbb $1/gi;

JS:

someStr = someStr.replace(/aaa (\d+)/gi, 'bbb $1');

Regular expression loop all matches

Perl:

for( 'aaa bbb' =~ /\w+/g ) {
    print "$_\n";
}

JS:

'aaa bbb'.match(/\w+/g).forEach( _ => {
    console.log(_);
});

// or:

for( _ of 'aaa bbb'.match(/\w+/g) ) {
    console.log(_);
}

Regular expression extraction

Perl:

my ( $a, $b ) = $someStr =~ /(aaa+*)(bbb+*)/;

JS:

const [ , a, b ] = /(aaa+*)(bbb+*)/.exec(someStr);
// or:
const [ , a, b ] = someStr.match(/(aaa+*)(bbb+*)/);

Regular expression named captures

Perl:

$someStr =~ /(?<myvar>foo)/;
print $+{myvar};  # foo

JS:

const { groups: { myvar } } = /(?<myvar>foo)/.exec(someStr);
console.log(myvar);

Regular expression precompiled

Perl:

my $re = qr/\w+/g;
for my $str ( @strs ) {
    my @matches = $str =~ $re;
    ...
}

JS:

const re = new RegExp('\w+', 'g');
for( const str of strs ) {
    const matches = re.exec(str);
    ...
}

Deconstructing with default values

Perl:

my $foo = $someHash{ foo } // 'mydefault';
my $bar = $someHash{ bar } // 11;

JS:

const { foo = 'mydefault', bar = {} } = someObj;

Check if is an Array, Object or a given class

Perl:

if( ref $myvar eq 'ARRAY' ) { ... }
elsif( ref $myvar eq 'HASH' ) { ... }
elsif( ref $myvar eq 'MyClass' ) { ... }

JS:

if( Array.isArray(myvar) ) { ... }
else if( typeof myvar === 'object' ) { ... } // careful: arrays are object too
else if( myvar instanceof MyClass ) { ... }

Using dates, convert from/to ISO

Perl:

# there's many ways to do it...
use POSIX qw(strftime);
my $now = localtime;
my $date = strftime "%m/%d/%Y", $now;

# parse it

my $format = DateTime::Format::Strptime->new( pattern => '%FT%T%z');
my $dt = $format->parse_datetime( '2017-04-09T21:00:00-0400' );

# or

use DateTime;
my $now = DateTime->now()->iso8601();

JS:

const now = new Date();
const date = now.toISOString().substring(0,10);

// parse it
const nowAgain = new Date(date);  // sets time to midnight UTC

// today with timezone
const nowInNYC = new Date().toLocaleString("en-US", {timeZone: "America/New_York"})