31615
A resourceful newsletter featuring the latest and most important news, articles, books and updates in the world of #javascript 🚀 Don't miss our Quizzes! Let's chat: @nairihar
CHALLENGE
Читать полностью…
const obj = {
name: "Orion",
greet() {
const inner = () => {
console.log(this.name);
};
inner();
},
greetRegular: function () {
const inner = function () {
console.log(this?.name ?? "undefined");
};
inner();
},
};
obj.greet();
obj.greetRegular();
CHALLENGE
const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));Читать полностью…
const pipe = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
const double = x => x * 2;
const addTen = x => x + 10;
const square = x => x * x;
const negate = x => -x;
const transform1 = compose(negate, square, addTen, double);
const transform2 = pipe(double, addTen, square, negate);
const val = 3;
console.log(transform1(val), transform2(val));
CHALLENGE
Читать полностью…
const temperature = {
celsius: 22,
[Symbol.toPrimitive](hint) {
if (hint === 'number') {
return this.celsius;
}
if (hint === 'string') {
return `${this.celsius}°C`;
}
return this.celsius + 273.15;
}
};
console.log(`Temp: ${temperature}`);
console.log(temperature + 0);
console.log(temperature * 2);
console.log(+temperature);
CHALLENGE
class EventEmitter {
#listeners = new WeakMap();
#registry = new FinalizationRegistry((label) => {
console.log(`Cleaned up: ${label}`);
});
subscribe(target, callback) {
if (!this.#listeners.has(target)) {
this.#listeners.set(target, []);
}
this.#listeners.get(target).push(callback);
this.#registry.register(target, target.name ?? "unknown");
}
emit(target) {
const cbs = this.#listeners.get(target);
if (cbs) cbs.forEach(cb => cb());
}
}
const emitter = new EventEmitter();
let obj1 = { name: "sensor" };
let obj2 = { name: "timer" };
const ws = new WeakSet([obj1, obj2]);
emitter.subscribe(obj1, () => console.log("sensor fired"));
emitter.subscribe(obj2, () => console.log("timer fired"));
emitter.subscribe(obj1, () => console.log("sensor logged"));
emitter.emit(obj1);
console.log(ws.has(obj1));
obj1 = null;
console.log(ws.has({ name: "sensor" }));
Читать полностью…
CHALLENGE
Читать полностью…
function Vehicle(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
this.describe = function () {
return `${this.year} ${this.make} ${this.model}`;
};
}
Vehicle.prototype.age = function (currentYear) {
return currentYear - this.year;
};
const car = new Vehicle("Toyota", "Supra", 1998);
const bike = new Vehicle("Harley", "Sportster", 2005);
console.log(car.describe());
console.log(bike.age(2025));
console.log(car.constructor === Vehicle);
console.log(Object.getPrototypeOf(car) === Vehicle.prototype);
CHALLENGE
Читать полностью…
const p1 = new Promise((resolve) => {
console.log("A");
resolve("B");
});
const p2 = p1.then((val) => {
console.log(val);
return "C";
});
p2.then((val) => {
console.log(val);
});
console.log("D");
CHALLENGE
Читать полностью…
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.name = this.constructor.name;
this.statusCode = statusCode;
}
}
class ValidationError extends AppError {
constructor(message) {
super(message, 400);
this.fields = [];
}
}
function riskyOperation(value) {
if (value === null) throw new ValidationError("Null value");
if (value < 0) throw new AppError("Negative value", 422);
return value * 2;
}
const results = [];
for (const val of [10, null, -5, 3]) {
try {
results.push(riskyOperation(val));
} catch (e) {
if (e instanceof ValidationError) {
results.push(`Validation:${e.statusCode}`);
} else if (e instanceof AppError) {
results.push(`App:${e.statusCode}`);
} else {
results.push("Unknown");
}
}
}
console.log(results.join(" | "));
CHALLENGE
"use strict";Читать полностью…
function createCounter() {
let count = 0;
return {
increment() { count++; },
decrement() { count--; },
getCount() { return count; },
reset: () => { count = 0; }
};
}
const counter = createCounter();
counter.increment();
counter.increment();
counter.increment();
counter.decrement();
const { getCount, reset } = counter;
console.log(getCount());
reset();
console.log(counter.getCount());
🤔 Porting 100k Lines from TypeScript to Rust in a Month
A prolific JavaScript developer ported a Pokémon battle simulator to Rust and shares his experiences and techniques used to work around issues where Claude Code would get bogged down in such a large task. He notes “LLM-based coding agents are such a great new tool” but require “engineering expertise and constant babysitting”.
Christopher Chedeau
👀 Introducing LibPDF: PDF Parsing and Generation from TypeScript
LibPDF bills itself as ‘the PDF library TypeScript deserves’ and supports parsing, modifying, signing and generating PDFs with a modern API in Node, Bun, and the browser. GitHub repo.
Documenso
CHALLENGE
const obj = {
data: ['x', 'y', 'z'],
*[Symbol.iterator]() {
for (let i = this.data.length - 1; i >= 0; i--) {
yield this.data[i].toUpperCase();
}
}
};
const result = [];
for (const item of obj) {
result.push(item);
if (result.length === 2) break;
}
console.log(result.join('-'));
Читать полностью…
CHALLENGE
class Calculator {
constructor(value) {
this.value = value;
}
add(num) {
this.value += num;
return this;
}
multiply(num) {
this.value *= num;
return this;
}
}
const calc = new Calculator(5);
const addMethod = calc.add;
const result = addMethod.call(calc, 3).multiply(2);
console.log(result.value);
Читать полностью…
CHALLENGE
function processData() {
const results = [];
for (let i = 0; i < 3; i++) {
const multiplier = i + 1;
setTimeout(() => {
results.push(i * multiplier);
}, 0);
}
setTimeout(() => {
console.log(results.join(','));
}, 10);
}
processData();
Читать полностью…
CHALLENGE
function* innerGenerator() {
yield 1;
yield 2;
return 'inner-done';
}
function* outerGenerator() {
yield 'start';
const result = yield* innerGenerator();
yield result;
yield 'end';
}
const gen = outerGenerator();
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
console.log(gen.next().value);
Читать полностью…
CHALLENGE
function Vehicle(type) {
this.type = type;
this.wheels = 4;
}
Vehicle.prototype.getInfo = function() {
return `${this.type} with ${this.wheels} wheels`;
};
const car = new Vehicle('sedan');
const bike = Vehicle('motorcycle');
console.log(car.getInfo());
console.log(typeof bike);
console.log(bike?.type || 'undefined');
Читать полностью…
🥶 Announcing TypeScript 6.0
Over six months in the making, TypeScript 6.0 is designed to bridge the gap between its self-hosted compiler and the (almost ready) Go-powered native compiler of TypeScript 7.0 .
There are new features (Temporal improvements, RegExp.escape, and more), but most important are the changes to help you prepare for 7.0:
• Numerous default changes: strict is now true, module is esnext, rootDir defaults to ., and more.
• A change that will affect many apps is types defaulting to [] rather than pulling in everything from node_modules/@types.
• Numerous deprecations: the es5 target, emitting AMD, UMD, and SystemJS modules, --baseUrl, and others.
• --stableTypeOrdering makes 6.0's type ordering behavior match 7.0's to help diagnose inference differences as you update.
Daniel Rosenwasser (Microsoft)
CHALLENGE
Читать полностью…
const a = 10n ** 3n;
const b = BigInt(Number.MAX_SAFE_INTEGER) + 1n;
const c = b + 1n;
console.log(typeof a);
console.log(a === 1000n);
console.log(b === c);
console.log(5n / 2n);
🤟 Evolving the Node.js Release Schedule: A Work in Progress
The Node.js team has long been discussing shifting Node to a new schedule of one major release per year (instead of two), removing the odd/even distinction, and making every release LTS (with a prior 11 months of alpha/current status). This is a preview post not intended for final publication till April, so things are subject to change (backup version).
The Node.js Team
🥶 Patreon has shared the tale of its seven year migration from JavaScript to TypeScript. There's a focus on tooling choices that might be useful if you're making a similar shift.
Читать полностью…
📈 In The 49MB Web Page, Shubham Bose expresses surprise at finding that loading a single NY Times page results in 422 network requests and 49 megabytes of data transferred. He reflects on the problems that have led to this being a common experience on news sites.
Читать полностью…
✌️ Temporal: The 9-Year Journey to Fix Time in JavaScript
JavaScript’s date/time handling is notoriously messy and libraries like Moment.js became popular as a way to work around it. In 2017, Maggie Johnson-Pint, a maintainer of Moment.js, proposed the Temporal API to fix date/time handling for good, and we’re mostly there (support is growing, with Safari and Node to catch up).
Jason Williams (Bloomberg)
CHALLENGE
Читать полностью…
const p1 = new Promise((resolve) => {
console.log("A");
resolve("X");
});
const p2 = p1.then((val) => {
console.log("B");
return val + "Y";
});
const p3 = p2.then((val) => {
console.log("C:", val);
});
console.log("D");
🚨 𝟭𝟱𝟬+ 𝗚𝗶𝘁𝗛𝘂𝗯 𝗿𝗲𝗽𝗼𝘀𝗶𝘁𝗼𝗿𝗶𝗲𝘀 𝗰𝗼𝗺𝗽𝗿𝗼𝗺𝗶𝘀𝗲𝗱 𝗯𝘆 𝗚𝗹𝗮𝘀𝘀𝗪𝗼𝗿𝗺 𝗠𝗮𝗹𝘄𝗮𝗿𝗲
Читать полностью…
CHALLENGE
const wm = new WeakMap();Читать полностью…
let obj1 = { name: 'John' };
let obj2 = { name: 'Jane' };
wm.set(obj1, 'developer');
wm.set(obj2, 'designer');
console.log(wm.get(obj1));
console.log(wm.has(obj2));
obj1 = null;
console.log(wm.get(obj1));
const normalObj = {};
try {
wm.set('string', 'value');
} catch (e) {
console.log('error');
}
CHALLENGE
const x = 15;Читать полностью…
const y = 10;
const z = 3;
const result1 = x & y;
const result2 = x | y;
const result3 = x ^ y;
const result4 = ~x;
const result5 = y << z;
const result6 = y >> 1;
console.log(`${result1},${result2},${result3},${result4},${result5},${result6}`);
CHALLENGE
class EventEmitter {
constructor() {
this.events = new Map();
}
on(event, callback) {
if (!this.events.has(event)) {
this.events.set(event, []);
}
this.events.get(event).push(callback);
return this;
}
emit(event, ...args) {
const callbacks = this.events.get(event);
if (callbacks) {
callbacks.forEach(cb => cb(...args));
}
return this;
}
}
const emitter = new EventEmitter();
emitter.on('test', x => console.log(x * 2))
.on('test', x => console.log(x + 10))
.emit('test', 5);
Читать полностью…
👀 Superdiff 4.0: Compares Arrays or Objects and Returns a Diff
Got two similar objects or arrays and want to see the underlying differences? Superdiff has been around a while, but recent updates boost performance, add support for streamed input and using a worker for more efficient diffing in a background thread. The project now has a handy documentation site too.
antoine
Whether you agree or not, Ryan Dahl, the original creator of both Node.js and Deno, drew a lot of attention for a post on X (above) where he shared a thought on the shifting roles of modern software engineers in an agentic world.
Читать полностью…
💎 Happy 20th Birthday jQuery!
On January 14, 2006, John Resig introduced a JavaScript library called jQuery at BarCamp in New York City....
Timmy Willison
🤟 Node.js Becomes a First-Class Citizen in Microsoft Aspire
Aspire is a Microsoft framework for orchestrating the development and deployment of distributed applications. Originally just targeting .NET, the new Aspire 13 makes JavaScript a first-class citizen, so you can now run Vite, Node.js, and full-stack JS apps with service discovery, built-in telemetry, and production-ready containers.
Microsoft