[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M716BXPY45XT13P1MHY1W6AX":3,"skill-same:01M716BXPY45XT13P1MHY1W6AX":61},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":35,"linkOnly":36,"markdownContent":37,"markdownBody":38,"frontMatter":39,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":14,"repositoryHtmlUrl":44,"repositoryHomepageUrl":6,"ownerHtmlUrl":45,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":46,"install":47,"resources":60},"01M716BXPY45XT13P1MHY1W6AX","javascript-mastery",null,"33+ essential JavaScript concepts every developer should know, inspired by [33-js-concepts](https:\u002F\u002Fgithub.com\u002Fleonardomso\u002F33-js-concepts).","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcursor\u002Fjavascript-mastery\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34],"javascript","javascript mastery","github","https","developer","js","community","essential","concepts","unknown","2026","2026-11-10 10:12:30",false,"---\nname: javascript-mastery\ndescription: \"33+ essential JavaScript concepts every developer should know, inspired by [33-js-concepts](https:\u002F\u002Fgithub.com\u002Fleonardomso\u002F33-js-concepts).\"\nrisk: unknown\nsource: community\ndate_added: \"2026-02-27\"\n---\n\n# 🧠 JavaScript Mastery\n\n> 33+ essential JavaScript concepts every developer should know, inspired by [33-js-concepts](https:\u002F\u002Fgithub.com\u002Fleonardomso\u002F33-js-concepts).\n\n## When to Use This Skill\n\nUse this skill when:\n\n- Explaining JavaScript concepts\n- Debugging tricky JS behavior\n- Teaching JavaScript fundamentals\n- Reviewing code for JS best practices\n- Understanding language quirks\n\n---\n\n## 1. Fundamentals\n\n### 1.1 Primitive Types\n\nJavaScript has 7 primitive types:\n\n```javascript\n\u002F\u002F String\nconst str = \"hello\";\n\n\u002F\u002F Number (integers and floats)\nconst num = 42;\nconst float = 3.14;\n\n\u002F\u002F BigInt (for large integers)\nconst big = 9007199254740991n;\n\n\u002F\u002F Boolean\nconst bool = true;\n\n\u002F\u002F Undefined\nlet undef; \u002F\u002F undefined\n\n\u002F\u002F Null\nconst empty = null;\n\n\u002F\u002F Symbol (unique identifiers)\nconst sym = Symbol(\"description\");\n```\n\n**Key points**:\n\n- Primitives are immutable\n- Passed by value\n- `typeof null === \"object\"` is a historical bug\n\n### 1.2 Type Coercion\n\nJavaScript implicitly converts types:\n\n```javascript\n\u002F\u002F String coercion\n\"5\" + 3; \u002F\u002F \"53\" (number → string)\n\"5\" - 3; \u002F\u002F 2    (string → number)\n\n\u002F\u002F Boolean coercion\nBoolean(\"\"); \u002F\u002F false\nBoolean(\"hello\"); \u002F\u002F true\nBoolean(0); \u002F\u002F false\nBoolean([]); \u002F\u002F true (!)\n\n\u002F\u002F Equality coercion\n\"5\" == 5; \u002F\u002F true  (coerces)\n\"5\" === 5; \u002F\u002F false (strict)\n```\n\n**Falsy values** (8 total):\n`false`, `0`, `-0`, `0n`, `\"\"`, `null`, `undefined`, `NaN`\n\n### 1.3 Equality Operators\n\n```javascript\n\u002F\u002F == (loose equality) - coerces types\nnull == undefined; \u002F\u002F true\n\"1\" == 1; \u002F\u002F true\n\n\u002F\u002F === (strict equality) - no coercion\nnull === undefined; \u002F\u002F false\n\"1\" === 1; \u002F\u002F false\n\n\u002F\u002F Object.is() - handles edge cases\nObject.is(NaN, NaN); \u002F\u002F true (NaN === NaN is false!)\nObject.is(-0, 0); \u002F\u002F false (0 === -0 is true!)\n```\n\n**Rule**: Always use `===` unless you have a specific reason not to.\n\n---\n\n## 2. Scope & Closures\n\n### 2.1 Scope Types\n\n```javascript\n\u002F\u002F Global scope\nvar globalVar = \"global\";\n\nfunction outer() {\n  \u002F\u002F Function scope\n  var functionVar = \"function\";\n\n  if (true) {\n    \u002F\u002F Block scope (let\u002Fconst only)\n    let blockVar = \"block\";\n    const alsoBlock = \"block\";\n    var notBlock = \"function\"; \u002F\u002F var ignores blocks!\n  }\n}\n```\n\n### 2.2 Closures\n\nA closure is a function that remembers its lexical scope:\n\n```javascript\nfunction createCounter() {\n  let count = 0; \u002F\u002F \"closed over\" variable\n\n  return {\n    increment() {\n      return ++count;\n    },\n    decrement() {\n      return --count;\n    },\n    getCount() {\n      return count;\n    },\n  };\n}\n\nconst counter = createCounter();\ncounter.increment(); \u002F\u002F 1\ncounter.increment(); \u002F\u002F 2\ncounter.getCount(); \u002F\u002F 2\n```\n\n**Common use cases**:\n\n- Data privacy (module pattern)\n- Function factories\n- Partial application\n- Memoization\n\n### 2.3 var vs let vs const\n\n```javascript\n\u002F\u002F var - function scoped, hoisted, can redeclare\nvar x = 1;\nvar x = 2; \u002F\u002F OK\n\n\u002F\u002F let - block scoped, hoisted (TDZ), no redeclare\nlet y = 1;\n\u002F\u002F let y = 2; \u002F\u002F Error!\n\n\u002F\u002F const - like let, but can't reassign\nconst z = 1;\n\u002F\u002F z = 2; \u002F\u002F Error!\n\n\u002F\u002F BUT: const objects are mutable\nconst obj = { a: 1 };\nobj.a = 2; \u002F\u002F OK\nobj.b = 3; \u002F\u002F OK\n```\n\n---\n\n## 3. Functions & Execution\n\n### 3.1 Call Stack\n\n```javascript\nfunction first() {\n  console.log(\"first start\");\n  second();\n  console.log(\"first end\");\n}\n\nfunction second() {\n  console.log(\"second\");\n}\n\nfirst();\n\u002F\u002F Output:\n\u002F\u002F \"first start\"\n\u002F\u002F \"second\"\n\u002F\u002F \"first end\"\n```\n\nStack overflow example:\n\n```javascript\nfunction infinite() {\n  infinite(); \u002F\u002F No base case!\n}\ninfinite(); \u002F\u002F RangeError: Maximum call stack size exceeded\n```\n\n### 3.2 Hoisting\n\n```javascript\n\u002F\u002F Variable hoisting\nconsole.log(a); \u002F\u002F undefined (hoisted, not initialized)\nvar a = 5;\n\nconsole.log(b); \u002F\u002F ReferenceError (TDZ)\nlet b = 5;\n\n\u002F\u002F Function hoisting\nsayHi(); \u002F\u002F Works!\nfunction sayHi() {\n  console.log(\"Hi!\");\n}\n\n\u002F\u002F Function expressions don't hoist\nsayBye(); \u002F\u002F TypeError\nvar sayBye = function () {\n  console.log(\"Bye!\");\n};\n```\n\n### 3.3 this Keyword\n\n```javascript\n\u002F\u002F Global context\nconsole.log(this); \u002F\u002F window (browser) or global (Node)\n\n\u002F\u002F Object method\nconst obj = {\n  name: \"Alice\",\n  greet() {\n    console.log(this.name); \u002F\u002F \"Alice\"\n  },\n};\n\n\u002F\u002F Arrow functions (lexical this)\nconst obj2 = {\n  name: \"Bob\",\n  greet: () => {\n    console.log(this.name); \u002F\u002F undefined (inherits outer this)\n  },\n};\n\n\u002F\u002F Explicit binding\nfunction greet() {\n  console.log(this.name);\n}\ngreet.call({ name: \"Charlie\" }); \u002F\u002F \"Charlie\"\ngreet.apply({ name: \"Diana\" }); \u002F\u002F \"Diana\"\nconst bound = greet.bind({ name: \"Eve\" });\nbound(); \u002F\u002F \"Eve\"\n```\n\n---\n\n## 4. Event Loop & Async\n\n### 4.1 Event Loop\n\n```javascript\nconsole.log(\"1\");\n\nsetTimeout(() => console.log(\"2\"), 0);\n\nPromise.resolve().then(() => console.log(\"3\"));\n\nconsole.log(\"4\");\n\n\u002F\u002F Output: 1, 4, 3, 2\n\u002F\u002F Why? Microtasks (Promises) run before macrotasks (setTimeout)\n```\n\n**Execution order**:\n\n1. Synchronous code (call stack)\n2. Microtasks (Promise callbacks, queueMicrotask)\n3. Macrotasks (setTimeout, setInterval, I\u002FO)\n\n### 4.2 Callbacks\n\n```javascript\n\u002F\u002F Callback pattern\nfunction fetchData(callback) {\n  setTimeout(() => {\n    callback(null, { data: \"result\" });\n  }, 1000);\n}\n\n\u002F\u002F Error-first convention\nfetchData((error, result) => {\n  if (error) {\n    console.error(error);\n    return;\n  }\n  console.log(result);\n});\n\n\u002F\u002F Callback hell (avoid this!)\ngetData((data) => {\n  processData(data, (processed) => {\n    saveData(processed, (saved) => {\n      notify(saved, () => {\n        \u002F\u002F 😱 Pyramid of doom\n      });\n    });\n  });\n});\n```\n\n### 4.3 Promises\n\n```javascript\n\u002F\u002F Creating a Promise\nconst promise = new Promise((resolve, reject) => {\n  setTimeout(() => {\n    resolve(\"Success!\");\n    \u002F\u002F or: reject(new Error(\"Failed!\"));\n  }, 1000);\n});\n\n\u002F\u002F Consuming Promises\npromise\n  .then((result) => console.log(result))\n  .catch((error) => console.error(error))\n  .finally(() => console.log(\"Done\"));\n\n\u002F\u002F Promise combinators\nPromise.all([p1, p2, p3]); \u002F\u002F All must succeed\nPromise.allSettled([p1, p2]); \u002F\u002F Wait for all, get status\nPromise.race([p1, p2]); \u002F\u002F First to settle\nPromise.any([p1, p2]); \u002F\u002F First to succeed\n```\n\n### 4.4 async\u002Fawait\n\n```javascript\nasync function fetchUserData(userId) {\n  try {\n    const response = await fetch(`\u002Fapi\u002Fusers\u002F${userId}`);\n    if (!response.ok) throw new Error(\"Failed to fetch\");\n    const user = await response.json();\n    return user;\n  } catch (error) {\n    console.error(\"Error:\", error);\n    throw error; \u002F\u002F Re-throw for caller to handle\n  }\n}\n\n\u002F\u002F Parallel execution\nasync function fetchAll() {\n  const [users, posts] = await Promise.all([\n    fetch(\"\u002Fapi\u002Fusers\"),\n    fetch(\"\u002Fapi\u002Fposts\"),\n  ]);\n  return { users, posts };\n}\n```\n\n---\n\n## 5. Functional Programming\n\n### 5.1 Higher-Order Functions\n\nFunctions that take or return functions:\n\n```javascript\n\u002F\u002F Takes a function\nconst numbers = [1, 2, 3];\nconst doubled = numbers.map((n) => n * 2); \u002F\u002F [2, 4, 6]\n\n\u002F\u002F Returns a function\nfunction multiply(a) {\n  return function (b) {\n    return a * b;\n  };\n}\nconst double = multiply(2);\ndouble(5); \u002F\u002F 10\n```\n\n### 5.2 Pure Functions\n\n```javascript\n\u002F\u002F Pure: same input → same output, no side effects\nfunction add(a, b) {\n  return a + b;\n}\n\n\u002F\u002F Impure: modifies external state\nlet total = 0;\nfunction addToTotal(value) {\n  total += value; \u002F\u002F Side effect!\n  return total;\n}\n\n\u002F\u002F Impure: depends on external state\nfunction getDiscount(price) {\n  return price * globalDiscountRate; \u002F\u002F External dependency\n}\n```\n\n### 5.3 map, filter, reduce\n\n```javascript\nconst users = [\n  { name: \"Alice\", age: 25 },\n  { name: \"Bob\", age: 30 },\n  { name: \"Charlie\", age: 35 },\n];\n\n\u002F\u002F map: transform each element\nconst names = users.map((u) => u.name);\n\u002F\u002F [\"Alice\", \"Bob\", \"Charlie\"]\n\n\u002F\u002F filter: keep elements matching condition\nconst adults = users.filter((u) => u.age >= 30);\n\u002F\u002F [{ name: \"Bob\", ... }, { name: \"Charlie\", ... }]\n\n\u002F\u002F reduce: accumulate into single value\nconst totalAge = users.reduce((sum, u) => sum + u.age, 0);\n\u002F\u002F 90\n\n\u002F\u002F Chaining\nconst result = users\n  .filter((u) => u.age >= 30)\n  .map((u) => u.name)\n  .join(\", \");\n\u002F\u002F \"Bob, Charlie\"\n```\n\n### 5.4 Currying & Composition\n\n```javascript\n\u002F\u002F Currying: transform f(a, b, c) into f(a)(b)(c)\nconst curry = (fn) => {\n  return function curried(...args) {\n    if (args.length >= fn.length) {\n      return fn.apply(this, args);\n    }\n    return (...moreArgs) => curried(...args, ...moreArgs);\n  };\n};\n\nconst add = curry((a, b, c) => a + b + c);\nadd(1)(2)(3); \u002F\u002F 6\nadd(1, 2)(3); \u002F\u002F 6\nadd(1)(2, 3); \u002F\u002F 6\n\n\u002F\u002F Composition: combine functions\nconst compose =\n  (...fns) =>\n  (x) =>\n    fns.reduceRight((acc, fn) => fn(acc), x);\n\nconst pipe =\n  (...fns) =>\n  (x) =>\n    fns.reduce((acc, fn) => fn(acc), x);\n\nconst addOne = (x) => x + 1;\nconst double = (x) => x * 2;\n\nconst addThenDouble = compose(double, addOne);\naddThenDouble(5); \u002F\u002F 12 = (5 + 1) * 2\n\nconst doubleThenAdd = pipe(double, addOne);\ndoubleThenAdd(5); \u002F\u002F 11 = (5 * 2) + 1\n```\n\n---\n\n## 6. Objects & Prototypes\n\n### 6.1 Prototypal Inheritance\n\n```javascript\n\u002F\u002F Prototype chain\nconst animal = {\n  speak() {\n    console.log(\"Some sound\");\n  },\n};\n\nconst dog = Object.create(animal);\ndog.bark = function () {\n  console.log(\"Woof!\");\n};\n\ndog.speak(); \u002F\u002F \"Some sound\" (inherited)\ndog.bark(); \u002F\u002F \"Woof!\" (own method)\n\n\u002F\u002F ES6 Classes (syntactic sugar)\nclass Animal {\n  speak() {\n    console.log(\"Some sound\");\n  }\n}\n\nclass Dog extends Animal {\n  bark() {\n    console.log(\"Woof!\");\n  }\n}\n```\n\n### 6.2 Object Methods\n\n```javascript\nconst obj = { a: 1, b: 2 };\n\n\u002F\u002F Keys, values, entries\nObject.keys(obj); \u002F\u002F [\"a\", \"b\"]\nObject.values(obj); \u002F\u002F [1, 2]\nObject.entries(obj); \u002F\u002F [[\"a\", 1], [\"b\", 2]]\n\n\u002F\u002F Shallow copy\nconst copy = { ...obj };\nconst copy2 = Object.assign({}, obj);\n\n\u002F\u002F Freeze (immutable)\nconst frozen = Object.freeze({ x: 1 });\nfrozen.x = 2; \u002F\u002F Silently fails (or throws in strict mode)\n\n\u002F\u002F Seal (no add\u002Fdelete, can modify)\nconst sealed = Object.seal({ x: 1 });\nsealed.x = 2; \u002F\u002F OK\nsealed.y = 3; \u002F\u002F Fails\ndelete sealed.x; \u002F\u002F Fails\n```\n\n---\n\n## 7. Modern JavaScript (ES6+)\n\n### 7.1 Destructuring\n\n```javascript\n\u002F\u002F Array destructuring\nconst [first, second, ...rest] = [1, 2, 3, 4, 5];\n\u002F\u002F first = 1, second = 2, rest = [3, 4, 5]\n\n\u002F\u002F Object destructuring\nconst { name, age, city = \"Unknown\" } = { name: \"Alice\", age: 25 };\n\u002F\u002F name = \"Alice\", age = 25, city = \"Unknown\"\n\n\u002F\u002F Renaming\nconst { name: userName } = { name: \"Bob\" };\n\u002F\u002F userName = \"Bob\"\n\n\u002F\u002F Nested\nconst {\n  address: { street },\n} = { address: { street: \"123 Main\" } };\n```\n\n### 7.2 Spread & Rest\n\n```javascript\n\u002F\u002F Spread: expand iterable\nconst arr1 = [1, 2, 3];\nconst arr2 = [...arr1, 4, 5]; \u002F\u002F [1, 2, 3, 4, 5]\n\nconst obj1 = { a: 1 };\nconst obj2 = { ...obj1, b: 2 }; \u002F\u002F { a: 1, b: 2 }\n\n\u002F\u002F Rest: collect remaining\nfunction sum(...numbers) {\n  return numbers.reduce((a, b) => a + b, 0);\n}\nsum(1, 2, 3, 4); \u002F\u002F 10\n```\n\n### 7.3 Modules\n\n```javascript\n\u002F\u002F Named exports\nexport const PI = 3.14159;\nexport function square(x) {\n  return x * x;\n}\n\n\u002F\u002F Default export\nexport default class Calculator {}\n\n\u002F\u002F Importing\nimport Calculator, { PI, square } from \".\u002Fmath.js\";\nimport * as math from \".\u002Fmath.js\";\n\n\u002F\u002F Dynamic import\nconst module = await import(\".\u002Fdynamic.js\");\n```\n\n### 7.4 Optional Chaining & Nullish Coalescing\n\n```javascript\n\u002F\u002F Optional chaining (?.)\nconst user = { address: { city: \"NYC\" } };\nconst city = user?.address?.city; \u002F\u002F \"NYC\"\nconst zip = user?.address?.zip; \u002F\u002F undefined (no error)\nconst fn = user?.getName?.(); \u002F\u002F undefined if no method\n\n\u002F\u002F Nullish coalescing (??)\nconst value = null ?? \"default\"; \u002F\u002F \"default\"\nconst zero = 0 ?? \"default\"; \u002F\u002F 0 (not nullish!)\nconst empty = \"\" ?? \"default\"; \u002F\u002F \"\" (not nullish!)\n\n\u002F\u002F Compare with ||\nconst value2 = 0 || \"default\"; \u002F\u002F \"default\" (0 is falsy)\n```\n\n---\n\n## Quick Reference Card\n\n| Concept        | Key Point                         |\n| :------------- | :-------------------------------- |\n| `==` vs `===`  | Always use `===`                  |\n| `var` vs `let` | Prefer `let`\u002F`const`              |\n| Closures       | Function + lexical scope          |\n| `this`         | Depends on how function is called |\n| Event loop     | Microtasks before macrotasks      |\n| Pure functions | Same input → same output          |\n| Prototypes     | `__proto__` → prototype chain     |\n| `??` vs `\\|\\|` | `??` only checks null\u002Fundefined   |\n\n---\n\n## Resources\n\n- [33 JS Concepts](https:\u002F\u002Fgithub.com\u002Fleonardomso\u002F33-js-concepts)\n- [JavaScript.info](https:\u002F\u002Fjavascript.info\u002F)\n- [MDN JavaScript Guide](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide)\n- [You Don't Know JS](https:\u002F\u002Fgithub.com\u002Fgetify\u002FYou-Dont-Know-JS)\n","# 🧠 JavaScript Mastery\n\n> 33+ essential JavaScript concepts every developer should know, inspired by [33-js-concepts](https:\u002F\u002Fgithub.com\u002Fleonardomso\u002F33-js-concepts).\n\n## When to Use This Skill\n\nUse this skill when:\n\n- Explaining JavaScript concepts\n- Debugging tricky JS behavior\n- Teaching JavaScript fundamentals\n- Reviewing code for JS best practices\n- Understanding language quirks\n\n---\n\n## 1. Fundamentals\n\n### 1.1 Primitive Types\n\nJavaScript has 7 primitive types:\n\n```javascript\n\u002F\u002F String\nconst str = \"hello\";\n\n\u002F\u002F Number (integers and floats)\nconst num = 42;\nconst float = 3.14;\n\n\u002F\u002F BigInt (for large integers)\nconst big = 9007199254740991n;\n\n\u002F\u002F Boolean\nconst bool = true;\n\n\u002F\u002F Undefined\nlet undef; \u002F\u002F undefined\n\n\u002F\u002F Null\nconst empty = null;\n\n\u002F\u002F Symbol (unique identifiers)\nconst sym = Symbol(\"description\");\n```\n\n**Key points**:\n\n- Primitives are immutable\n- Passed by value\n- `typeof null === \"object\"` is a historical bug\n\n### 1.2 Type Coercion\n\nJavaScript implicitly converts types:\n\n```javascript\n\u002F\u002F String coercion\n\"5\" + 3; \u002F\u002F \"53\" (number → string)\n\"5\" - 3; \u002F\u002F 2    (string → number)\n\n\u002F\u002F Boolean coercion\nBoolean(\"\"); \u002F\u002F false\nBoolean(\"hello\"); \u002F\u002F true\nBoolean(0); \u002F\u002F false\nBoolean([]); \u002F\u002F true (!)\n\n\u002F\u002F Equality coercion\n\"5\" == 5; \u002F\u002F true  (coerces)\n\"5\" === 5; \u002F\u002F false (strict)\n```\n\n**Falsy values** (8 total):\n`false`, `0`, `-0`, `0n`, `\"\"`, `null`, `undefined`, `NaN`\n\n### 1.3 Equality Operators\n\n```javascript\n\u002F\u002F == (loose equality) - coerces types\nnull == undefined; \u002F\u002F true\n\"1\" == 1; \u002F\u002F true\n\n\u002F\u002F === (strict equality) - no coercion\nnull === undefined; \u002F\u002F false\n\"1\" === 1; \u002F\u002F false\n\n\u002F\u002F Object.is() - handles edge cases\nObject.is(NaN, NaN); \u002F\u002F true (NaN === NaN is false!)\nObject.is(-0, 0); \u002F\u002F false (0 === -0 is true!)\n```\n\n**Rule**: Always use `===` unless you have a specific reason not to.\n\n---\n\n## 2. Scope & Closures\n\n### 2.1 Scope Types\n\n```javascript\n\u002F\u002F Global scope\nvar globalVar = \"global\";\n\nfunction outer() {\n  \u002F\u002F Function scope\n  var functionVar = \"function\";\n\n  if (true) {\n    \u002F\u002F Block scope (let\u002Fconst only)\n    let blockVar = \"block\";\n    const alsoBlock = \"block\";\n    var notBlock = \"function\"; \u002F\u002F var ignores blocks!\n  }\n}\n```\n\n### 2.2 Closures\n\nA closure is a function that remembers its lexical scope:\n\n```javascript\nfunction createCounter() {\n  let count = 0; \u002F\u002F \"closed over\" variable\n\n  return {\n    increment() {\n      return ++count;\n    },\n    decrement() {\n      return --count;\n    },\n    getCount() {\n      return count;\n    },\n  };\n}\n\nconst counter = createCounter();\ncounter.increment(); \u002F\u002F 1\ncounter.increment(); \u002F\u002F 2\ncounter.getCount(); \u002F\u002F 2\n```\n\n**Common use cases**:\n\n- Data privacy (module pattern)\n- Function factories\n- Partial application\n- Memoization\n\n### 2.3 var vs let vs const\n\n```javascript\n\u002F\u002F var - function scoped, hoisted, can redeclare\nvar x = 1;\nvar x = 2; \u002F\u002F OK\n\n\u002F\u002F let - block scoped, hoisted (TDZ), no redeclare\nlet y = 1;\n\u002F\u002F let y = 2; \u002F\u002F Error!\n\n\u002F\u002F const - like let, but can't reassign\nconst z = 1;\n\u002F\u002F z = 2; \u002F\u002F Error!\n\n\u002F\u002F BUT: const objects are mutable\nconst obj = { a: 1 };\nobj.a = 2; \u002F\u002F OK\nobj.b = 3; \u002F\u002F OK\n```\n\n---\n\n## 3. Functions & Execution\n\n### 3.1 Call Stack\n\n```javascript\nfunction first() {\n  console.log(\"first start\");\n  second();\n  console.log(\"first end\");\n}\n\nfunction second() {\n  console.log(\"second\");\n}\n\nfirst();\n\u002F\u002F Output:\n\u002F\u002F \"first start\"\n\u002F\u002F \"second\"\n\u002F\u002F \"first end\"\n```\n\nStack overflow example:\n\n```javascript\nfunction infinite() {\n  infinite(); \u002F\u002F No base case!\n}\ninfinite(); \u002F\u002F RangeError: Maximum call stack size exceeded\n```\n\n### 3.2 Hoisting\n\n```javascript\n\u002F\u002F Variable hoisting\nconsole.log(a); \u002F\u002F undefined (hoisted, not initialized)\nvar a = 5;\n\nconsole.log(b); \u002F\u002F ReferenceError (TDZ)\nlet b = 5;\n\n\u002F\u002F Function hoisting\nsayHi(); \u002F\u002F Works!\nfunction sayHi() {\n  console.log(\"Hi!\");\n}\n\n\u002F\u002F Function expressions don't hoist\nsayBye(); \u002F\u002F TypeError\nvar sayBye = function () {\n  console.log(\"Bye!\");\n};\n```\n\n### 3.3 this Keyword\n\n```javascript\n\u002F\u002F Global context\nconsole.log(this); \u002F\u002F window (browser) or global (Node)\n\n\u002F\u002F Object method\nconst obj = {\n  name: \"Alice\",\n  greet() {\n    console.log(this.name); \u002F\u002F \"Alice\"\n  },\n};\n\n\u002F\u002F Arrow functions (lexical this)\nconst obj2 = {\n  name: \"Bob\",\n  greet: () => {\n    console.log(this.name); \u002F\u002F undefined (inherits outer this)\n  },\n};\n\n\u002F\u002F Explicit binding\nfunction greet() {\n  console.log(this.name);\n}\ngreet.call({ name: \"Charlie\" }); \u002F\u002F \"Charlie\"\ngreet.apply({ name: \"Diana\" }); \u002F\u002F \"Diana\"\nconst bound = greet.bind({ name: \"Eve\" });\nbound(); \u002F\u002F \"Eve\"\n```\n\n---\n\n## 4. Event Loop & Async\n\n### 4.1 Event Loop\n\n```javascript\nconsole.log(\"1\");\n\nsetTimeout(() => console.log(\"2\"), 0);\n\nPromise.resolve().then(() => console.log(\"3\"));\n\nconsole.log(\"4\");\n\n\u002F\u002F Output: 1, 4, 3, 2\n\u002F\u002F Why? Microtasks (Promises) run before macrotasks (setTimeout)\n```\n\n**Execution order**:\n\n1. Synchronous code (call stack)\n2. Microtasks (Promise callbacks, queueMicrotask)\n3. Macrotasks (setTimeout, setInterval, I\u002FO)\n\n### 4.2 Callbacks\n\n```javascript\n\u002F\u002F Callback pattern\nfunction fetchData(callback) {\n  setTimeout(() => {\n    callback(null, { data: \"result\" });\n  }, 1000);\n}\n\n\u002F\u002F Error-first convention\nfetchData((error, result) => {\n  if (error) {\n    console.error(error);\n    return;\n  }\n  console.log(result);\n});\n\n\u002F\u002F Callback hell (avoid this!)\ngetData((data) => {\n  processData(data, (processed) => {\n    saveData(processed, (saved) => {\n      notify(saved, () => {\n        \u002F\u002F 😱 Pyramid of doom\n      });\n    });\n  });\n});\n```\n\n### 4.3 Promises\n\n```javascript\n\u002F\u002F Creating a Promise\nconst promise = new Promise((resolve, reject) => {\n  setTimeout(() => {\n    resolve(\"Success!\");\n    \u002F\u002F or: reject(new Error(\"Failed!\"));\n  }, 1000);\n});\n\n\u002F\u002F Consuming Promises\npromise\n  .then((result) => console.log(result))\n  .catch((error) => console.error(error))\n  .finally(() => console.log(\"Done\"));\n\n\u002F\u002F Promise combinators\nPromise.all([p1, p2, p3]); \u002F\u002F All must succeed\nPromise.allSettled([p1, p2]); \u002F\u002F Wait for all, get status\nPromise.race([p1, p2]); \u002F\u002F First to settle\nPromise.any([p1, p2]); \u002F\u002F First to succeed\n```\n\n### 4.4 async\u002Fawait\n\n```javascript\nasync function fetchUserData(userId) {\n  try {\n    const response = await fetch(`\u002Fapi\u002Fusers\u002F${userId}`);\n    if (!response.ok) throw new Error(\"Failed to fetch\");\n    const user = await response.json();\n    return user;\n  } catch (error) {\n    console.error(\"Error:\", error);\n    throw error; \u002F\u002F Re-throw for caller to handle\n  }\n}\n\n\u002F\u002F Parallel execution\nasync function fetchAll() {\n  const [users, posts] = await Promise.all([\n    fetch(\"\u002Fapi\u002Fusers\"),\n    fetch(\"\u002Fapi\u002Fposts\"),\n  ]);\n  return { users, posts };\n}\n```\n\n---\n\n## 5. Functional Programming\n\n### 5.1 Higher-Order Functions\n\nFunctions that take or return functions:\n\n```javascript\n\u002F\u002F Takes a function\nconst numbers = [1, 2, 3];\nconst doubled = numbers.map((n) => n * 2); \u002F\u002F [2, 4, 6]\n\n\u002F\u002F Returns a function\nfunction multiply(a) {\n  return function (b) {\n    return a * b;\n  };\n}\nconst double = multiply(2);\ndouble(5); \u002F\u002F 10\n```\n\n### 5.2 Pure Functions\n\n```javascript\n\u002F\u002F Pure: same input → same output, no side effects\nfunction add(a, b) {\n  return a + b;\n}\n\n\u002F\u002F Impure: modifies external state\nlet total = 0;\nfunction addToTotal(value) {\n  total += value; \u002F\u002F Side effect!\n  return total;\n}\n\n\u002F\u002F Impure: depends on external state\nfunction getDiscount(price) {\n  return price * globalDiscountRate; \u002F\u002F External dependency\n}\n```\n\n### 5.3 map, filter, reduce\n\n```javascript\nconst users = [\n  { name: \"Alice\", age: 25 },\n  { name: \"Bob\", age: 30 },\n  { name: \"Charlie\", age: 35 },\n];\n\n\u002F\u002F map: transform each element\nconst names = users.map((u) => u.name);\n\u002F\u002F [\"Alice\", \"Bob\", \"Charlie\"]\n\n\u002F\u002F filter: keep elements matching condition\nconst adults = users.filter((u) => u.age >= 30);\n\u002F\u002F [{ name: \"Bob\", ... }, { name: \"Charlie\", ... }]\n\n\u002F\u002F reduce: accumulate into single value\nconst totalAge = users.reduce((sum, u) => sum + u.age, 0);\n\u002F\u002F 90\n\n\u002F\u002F Chaining\nconst result = users\n  .filter((u) => u.age >= 30)\n  .map((u) => u.name)\n  .join(\", \");\n\u002F\u002F \"Bob, Charlie\"\n```\n\n### 5.4 Currying & Composition\n\n```javascript\n\u002F\u002F Currying: transform f(a, b, c) into f(a)(b)(c)\nconst curry = (fn) => {\n  return function curried(...args) {\n    if (args.length >= fn.length) {\n      return fn.apply(this, args);\n    }\n    return (...moreArgs) => curried(...args, ...moreArgs);\n  };\n};\n\nconst add = curry((a, b, c) => a + b + c);\nadd(1)(2)(3); \u002F\u002F 6\nadd(1, 2)(3); \u002F\u002F 6\nadd(1)(2, 3); \u002F\u002F 6\n\n\u002F\u002F Composition: combine functions\nconst compose =\n  (...fns) =>\n  (x) =>\n    fns.reduceRight((acc, fn) => fn(acc), x);\n\nconst pipe =\n  (...fns) =>\n  (x) =>\n    fns.reduce((acc, fn) => fn(acc), x);\n\nconst addOne = (x) => x + 1;\nconst double = (x) => x * 2;\n\nconst addThenDouble = compose(double, addOne);\naddThenDouble(5); \u002F\u002F 12 = (5 + 1) * 2\n\nconst doubleThenAdd = pipe(double, addOne);\ndoubleThenAdd(5); \u002F\u002F 11 = (5 * 2) + 1\n```\n\n---\n\n## 6. Objects & Prototypes\n\n### 6.1 Prototypal Inheritance\n\n```javascript\n\u002F\u002F Prototype chain\nconst animal = {\n  speak() {\n    console.log(\"Some sound\");\n  },\n};\n\nconst dog = Object.create(animal);\ndog.bark = function () {\n  console.log(\"Woof!\");\n};\n\ndog.speak(); \u002F\u002F \"Some sound\" (inherited)\ndog.bark(); \u002F\u002F \"Woof!\" (own method)\n\n\u002F\u002F ES6 Classes (syntactic sugar)\nclass Animal {\n  speak() {\n    console.log(\"Some sound\");\n  }\n}\n\nclass Dog extends Animal {\n  bark() {\n    console.log(\"Woof!\");\n  }\n}\n```\n\n### 6.2 Object Methods\n\n```javascript\nconst obj = { a: 1, b: 2 };\n\n\u002F\u002F Keys, values, entries\nObject.keys(obj); \u002F\u002F [\"a\", \"b\"]\nObject.values(obj); \u002F\u002F [1, 2]\nObject.entries(obj); \u002F\u002F [[\"a\", 1], [\"b\", 2]]\n\n\u002F\u002F Shallow copy\nconst copy = { ...obj };\nconst copy2 = Object.assign({}, obj);\n\n\u002F\u002F Freeze (immutable)\nconst frozen = Object.freeze({ x: 1 });\nfrozen.x = 2; \u002F\u002F Silently fails (or throws in strict mode)\n\n\u002F\u002F Seal (no add\u002Fdelete, can modify)\nconst sealed = Object.seal({ x: 1 });\nsealed.x = 2; \u002F\u002F OK\nsealed.y = 3; \u002F\u002F Fails\ndelete sealed.x; \u002F\u002F Fails\n```\n\n---\n\n## 7. Modern JavaScript (ES6+)\n\n### 7.1 Destructuring\n\n```javascript\n\u002F\u002F Array destructuring\nconst [first, second, ...rest] = [1, 2, 3, 4, 5];\n\u002F\u002F first = 1, second = 2, rest = [3, 4, 5]\n\n\u002F\u002F Object destructuring\nconst { name, age, city = \"Unknown\" } = { name: \"Alice\", age: 25 };\n\u002F\u002F name = \"Alice\", age = 25, city = \"Unknown\"\n\n\u002F\u002F Renaming\nconst { name: userName } = { name: \"Bob\" };\n\u002F\u002F userName = \"Bob\"\n\n\u002F\u002F Nested\nconst {\n  address: { street },\n} = { address: { street: \"123 Main\" } };\n```\n\n### 7.2 Spread & Rest\n\n```javascript\n\u002F\u002F Spread: expand iterable\nconst arr1 = [1, 2, 3];\nconst arr2 = [...arr1, 4, 5]; \u002F\u002F [1, 2, 3, 4, 5]\n\nconst obj1 = { a: 1 };\nconst obj2 = { ...obj1, b: 2 }; \u002F\u002F { a: 1, b: 2 }\n\n\u002F\u002F Rest: collect remaining\nfunction sum(...numbers) {\n  return numbers.reduce((a, b) => a + b, 0);\n}\nsum(1, 2, 3, 4); \u002F\u002F 10\n```\n\n### 7.3 Modules\n\n```javascript\n\u002F\u002F Named exports\nexport const PI = 3.14159;\nexport function square(x) {\n  return x * x;\n}\n\n\u002F\u002F Default export\nexport default class Calculator {}\n\n\u002F\u002F Importing\nimport Calculator, { PI, square } from \".\u002Fmath.js\";\nimport * as math from \".\u002Fmath.js\";\n\n\u002F\u002F Dynamic import\nconst module = await import(\".\u002Fdynamic.js\");\n```\n\n### 7.4 Optional Chaining & Nullish Coalescing\n\n```javascript\n\u002F\u002F Optional chaining (?.)\nconst user = { address: { city: \"NYC\" } };\nconst city = user?.address?.city; \u002F\u002F \"NYC\"\nconst zip = user?.address?.zip; \u002F\u002F undefined (no error)\nconst fn = user?.getName?.(); \u002F\u002F undefined if no method\n\n\u002F\u002F Nullish coalescing (??)\nconst value = null ?? \"default\"; \u002F\u002F \"default\"\nconst zero = 0 ?? \"default\"; \u002F\u002F 0 (not nullish!)\nconst empty = \"\" ?? \"default\"; \u002F\u002F \"\" (not nullish!)\n\n\u002F\u002F Compare with ||\nconst value2 = 0 || \"default\"; \u002F\u002F \"default\" (0 is falsy)\n```\n\n---\n\n## Quick Reference Card\n\n| Concept        | Key Point                         |\n| :------------- | :-------------------------------- |\n| `==` vs `===`  | Always use `===`                  |\n| `var` vs `let` | Prefer `let`\u002F`const`              |\n| Closures       | Function + lexical scope          |\n| `this`         | Depends on how function is called |\n| Event loop     | Microtasks before macrotasks      |\n| Pure functions | Same input → same output          |\n| Prototypes     | `__proto__` → prototype chain     |\n| `??` vs `\\|\\|` | `??` only checks null\u002Fundefined   |\n\n---\n\n## Resources\n\n- [33 JS Concepts](https:\u002F\u002Fgithub.com\u002Fleonardomso\u002F33-js-concepts)\n- [JavaScript.info](https:\u002F\u002Fjavascript.info\u002F)\n- [MDN JavaScript Guide](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide)\n- [You Don't Know JS](https:\u002F\u002Fgithub.com\u002Fgetify\u002FYou-Dont-Know-JS)\n",{"name":5,"risk":33,"source":30,"date_added":40,"description":7},"2026-02-27","main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fcursor\u002Fjavascript-mastery","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":48,"prompt":58,"zipAvailable":59},[49,52,55],{"tool":50,"command":51},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill javascript-mastery",{"tool":53,"command":54},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill javascript-mastery",{"tool":56,"command":57},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill javascript-mastery","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcursor\u002Fjavascript-mastery\u002FSKILL.md",true,[],[62,84,110,120,133,151],{"skillNo":63,"name":64,"nameZh":6,"description":65,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":66,"categories":67,"keywords":71,"publishedAt":35},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[68],{"categoryNo":69,"categoryName":70,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000037","律师与法务",[72,73,74,75,76,77,78,79,80,81,82,83],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch","with",{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":90,"publishedAt":35},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[91,92,93,94,95,96,74,97,98,99,100,101,102,103,104,105,106,107,108,109],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","when","brew","live","data","google","install","read","across","api",{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":35},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[117,118,91,102,103,104,105,95,74,107,119,108,109,101,99,98,97,106,96,94],"trend radar","radar","pulse",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":35},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[127,128,129,130,131,132],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":144,"publishedAt":35},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[139],{"categoryNo":140,"categoryName":141,"taxonomyType":142,"taxonomyTypeDesc":143},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",[135,80,145,146,147,83,102,148,27,149,93,150,106],"Audio","cli","youtube","images","files","pdfs",{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":157,"publishedAt":35},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[153,158,159,160,106,161,27,26,162,163,164,165],"status","play","go","latest","discover","control","cmd","volume"]