Why people think "JavaScript sucks"
It's popular
It's easier to make memes about it
There are only two kinds of languages: the ones people complain about and the ones nobody uses.
Created in 10 days
in 1995, it is now a quite different language
You are forced to use it
You have no choice on browser
Unknown Runtime
Every browsers has his own implementation of JavaScript
Too much tools
Mix between front-end and back-end modules
Too much modules
A
C v1.0
B
C v2.0
node_modules
a
b
node_modules
c
node_modules
c
A
C ^1.0
B
C ^1.1
node_modules
a
b
c
A
C v1.0
B
C v2.0
The left-pad incident
It's not JavaScript fault, but the community
Too much libraries
Back to the language
Async & Callbacks
fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})
Async & Callback
Solved with promises
const files = await readdir(source)
for (const file of files) {
const file = await readFile(file)
// ...
}
const files = await readdir(source)
const filesContent = await Promise.all(
files.map(file => readFile(file))
)
Unpredictable Language
[] + [] // ''
[] + {} // Object
{} + [] // 0
{} + {} // NaN
Unpredictable Language
[3, 10, 1].sort() // [1, 10, 3]
['1', '2', '3']
.map(parseInt) // [1, NaN, NaN]
Not typed
But there is TypeScript
Types are checked while transpiling
Dependency injection
<?php
class MaClass {
private Dep1 $dep;
function __construct(Dep1 $dep) {
$this->dep = $dep;
}
}
NestJS
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
findAll(): Cat[] {
return this.cats;
}
}
import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Get()
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
Adonis
import Route from '@ioc:Adonis/Core/Route'
Route.post('add-to-cart', async ({ request, response }) => {
/**
* Read cookie by name
*/
const existingItems = request.cookie('cart-items', [])
/**
* Set/update cookie
*/
const newItems = existingItems.concat([{ id: 10 }])
response.cookie('cart-items', newItems)
})
Route.delete('clear-cart', async ({ response }) => {
/**
* Clear cookie
*/
response.clearCookie('cart-items')
})
Single thread
Single thread
slice := []string{"a", "b", "c", "d", "e"}
sliceLength := len(slice)
var wg sync.WaitGroup
wg.Add(sliceLength)
for i := 0; i < sliceLength; i++ {
go func(i int) {
defer wg.Done()
slowFunction(slice[i])
}(i)
}
wg.Wait()
const slice = ["a", "b", "c", "d", "e"]
for (const item of items) {
slowFunction(item)
}
function readFile(id) {
const {file} = await mysql.first('SELECT file FROM files WHERE id = ?', [id])
const content = await readFile(file)
await mysql.execute('INSERT INTO post SET content = ?', [content])
}
await readFile(3)
Being critical
is important
Understanding is better
JavaScript sucks
By Jonathan Boyer
JavaScript sucks
- 227