All skills
ccheney avatar

/modern-javascript

@00695ba

Implement or debug JavaScript language behavior, including promise completion, async iteration, mutation, and runtime compatibility. Use for ECMAScript semantics or polyfill/transform choices; not unrelated framework or TypeScript type design.

Use this Skill: https://skilld.dev/gh/ccheney/robust-skills/modern-javascript

This session only. Nothing lands on disk.

referencesES2016-ES2017.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

ES2016 & ES2017 Features

Array.includes(), exponentiation operator, async/await, Object.values(), Object.entries(), String.padStart(), String.padEnd(), Object.getOwnPropertyDescriptors(), trailing commas in functions, SharedArrayBuffer, Atomics.

Contents

ES2016 (ES7)

The smallest ECMAScript release with just two features.

Array.prototype.includes()

Check if array contains a value (handles NaN correctly).

const arr = [1, 2, 3, NaN];

// ✅ includes() - handles NaN
arr.includes(2);      // true
arr.includes(4);      // false
arr.includes(NaN);    // true

// ❌ indexOf() - doesn't find NaN
arr.indexOf(NaN);     // -1 (wrong!)

// Optional start index
arr.includes(2, 2);   // false (starts searching from index 2)

Exponentiation Operator

// ❌ Before
Math.pow(2, 10);  // 1024

// ✅ ES2016
2 ** 10;  // 1024

// Right-associative
2 ** 3 ** 2;  // 2 ** 9 = 512 (not 8 ** 2)

// Assignment operator
let x = 2;
x **= 3;  // x = 8

ES2017 (ES8)

Async Functions

Syntactic sugar over Promises for cleaner asynchronous code.

// ❌ Promise chains
function fetchUserThen(id) {
  return fetch(`/api/users/${id}`)
    .then(res => res.json())
    .then(user => fetch(`/api/posts?userId=${user.id}`))
    .then(res => res.json())
    .catch(err => console.error(err));
}

// ✅ async/await
async function fetchUser(id) {
  try {
    const res = await fetch(`/api/users/${id}`);
    const user = await res.json();
    const postsRes = await fetch(`/api/posts?userId=${user.id}`);
    return await postsRes.json();
  } catch (err) {
    console.error(err);
  }
}

// Arrow function syntax
const fetchUserArrow = async (id) => {
  const res = await fetch(`/api/users/${id}`);
  return res.json();
};

// Async methods
const obj = {
  async getData() {
    return await fetchSomething();
  }
};

Object.values() and Object.entries()

const user = { name: 'Alice', age: 30, city: 'NYC' };

// Object.values() - get values array
Object.values(user);  // ['Alice', 30, 'NYC']

// Object.entries() - get [key, value] pairs
Object.entries(user);
// [['name', 'Alice'], ['age', 30], ['city', 'NYC']]

// Iterate over entries
for (const [key, value] of Object.entries(user)) {
  console.log(`${key}: ${value}`);
}

// Transform object
const doubled = Object.fromEntries(
  Object.entries(prices).map(([k, v]) => [k, v * 2])
);

String Padding

// padStart - pad from beginning
'5'.padStart(3, '0');      // '005'
'42'.padStart(5, '*');     // '***42'
'hello'.padStart(10);      // '     hello' (spaces)

// padEnd - pad from end
'5'.padEnd(3, '0');        // '500'
'hi'.padEnd(5, '.');       // 'hi...'

// Practical: Format numbers
const formatId = id => String(id).padStart(6, '0');
formatId(42);  // '000042'

// Practical: Align columns
const items = [['Apple', 1.5], ['Banana', 0.75]];
for (const [name, price] of items) {
  console.log(`${name.padEnd(10)}$${price.toFixed(2)}`);
}
// Apple     $1.50
// Banana    $0.75

Object.getOwnPropertyDescriptors()

Get all property descriptors at once (useful for proper object cloning).

const source = {
  name: 'Alice',
  get fullName() { return this.name; }
};

// ❌ Object.assign loses getters/setters
const bad = Object.assign({}, source);
Object.getOwnPropertyDescriptor(bad, 'fullName');
// { value: 'Alice', writable: true, ... }  <- Lost getter!

// ✅ Preserve descriptors
const good = Object.defineProperties(
  {},
  Object.getOwnPropertyDescriptors(source)
);
Object.getOwnPropertyDescriptor(good, 'fullName');
// { get: [Function], set: undefined, ... }  <- Getter preserved!

Trailing Commas in Function Parameters

// Now allowed (helps with cleaner diffs)
function greet(
  name,
  greeting,  // trailing comma OK
) {
  return `${greeting}, ${name}!`;
}

greet(
  'Alice',
  'Hello',  // trailing comma OK
);

SharedArrayBuffer and Atomics

Low-level multi-threading primitives (advanced).

In browsers, constructing or sharing a SharedArrayBuffer generally also requires a cross-origin-isolated document. That security policy is a web-platform requirement, separate from the ECMAScript API.

// Create shared memory
const buffer = new SharedArrayBuffer(16);
const view = new Int32Array(buffer);

// Atomic operations (thread-safe)
Atomics.store(view, 0, 42);
Atomics.load(view, 0);  // 42
Atomics.add(view, 0, 1);  // Returns 42, view[0] is now 43
Atomics.compareExchange(view, 0, 43, 100);  // If 43, set to 100

Source: SKILL.md on GitHub

No alerts14d4 checks · Risk SAFE
  • Gen Agent Trust Hub14d

    The skill provides a technical reference for modern JavaScript features and toolchains. It includes an indirect prompt injection surface by directing the agent to read and analyze project files, such as lockfiles and build configurations, which may contain untrusted data that could influence the agent's code generation logic.

  • Socket14d

    No alerts

  • Snyk14d

    Risk: LOW · No issues

  • Runlayer7mo

    12 files scanned · No issues

Signed by skilld at 00695ba. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 weeks ago.

Activeupdated 3 weeks ago

README badge

README badge for ccheney/robust-skills/modern-javascript