Array និង Object

មាតិកា

  1. រចនាសម្ព័ន្ធពីរសម្រាប់ស្ទើរតែគ្រប់យ៉ាង
  2. Object
  3. Array
  4. គម្រោងរបស់ Dara ជាទិន្នន័យ
  5. ការបំលែង Array៖ map, filter, find
  6. ការត្រួតពិនិត្យ និងការបញ្ចូលគ្នា៖ some, every, reduce, sort
  7. Destructuring, Spread និង Rest
  8. Optional Chaining និង Object Helper
  9. JSON
  10. ចម្លង ទល់នឹង យោង
  11. សាកល្បងដោយខ្លួនឯង

1. រចនាសម្ព័ន្ធពីរសម្រាប់ស្ទើរតែគ្រប់យ៉ាង

ឥឡូវនេះអ្នកមានតម្លៃតែមួយៗ (string, number, boolean)។ កម្មវិធីពិតធ្វើការជាមួយ ការប្រមូល នៃតម្លៃទាំងនោះ ហើយ JavaScript មានឧបករណ៍សំខាន់ពីរ៖

រចនាសម្ព័ន្ធប្រើសម្រាប់មើលទៅដូច
Arrayបញ្ជី របស់មានលំដាប់["HTML", "CSS"]
Objectអ្វីមួយដែលពិពណ៌នាដោយ property មានឈ្មោះ{ name: "Dara", city: "Phnom Penh" }

ទិន្នន័យភាគច្រើនដែលអ្នកជួប ចាប់ពីការឆ្លើយតបរបស់ web API ដល់ជួរក្នុង database គឺជា array និង object ដែលដាក់ក្នុងគ្នា។ ប្រសិនបើអ្នកអាន និងកែទម្រង់ទាំងពីរនេះបាន អ្នកអាចដោះស្រាយទិន្នន័យស្ទើរតែគ្រប់ប្រភេទ។

2. Object

Object គឺជាសំណុំនៃគូ key: value នៅក្នុងសញ្ញាអង្កាប់៖

const dara = {
  name: "Dara Sok",
  city: "Phnom Penh",
  skills: ["HTML", "CSS"],
};

អាន property ដោយសញ្ញាចុច ឬដោយសញ្ញាតង្កៀបការ៉េ នៅពេល key នៅក្នុង variable ឬមិនមែនជាឈ្មោះត្រឹមត្រូវ៖

console.log(dara.name); // "Dara Sok"
console.log(dara["city"]); // "Phnom Penh"

const key = "name";
console.log(dara[key]); // "Dara Sok"

អ្នកអាចផ្លាស់ប្តូរ បន្ថែម និងលុប property។ វាដំណើរការសូម្បីតែលើ object ដែលប្រកាសដោយ const ព្រោះ const ហាមអ្នកមិនឲ្យ កំណត់ variable ឡើងវិញ ប៉ុន្តែមិនហាមការផ្លាស់ប្តូរអ្វីដែលនៅខាងក្នុងទេ៖

dara.city = "Siem Reap"; // change
dara.available = true; // add
delete dara.available; // remove

3. Array

Array គឺជាបញ្ជីមានលំដាប់។ អ្នកបានជួបវានៅជំពូក loop; នេះជាប្រតិបត្តិការប្រចាំថ្ងៃ៖

const skills = ["HTML", "CSS"];

skills.push("JavaScript"); // add to the end
skills.pop(); // remove from the end, returns "JavaScript"
skills.unshift("Git"); // add to the start
skills.shift(); // remove from the start, returns "Git"

console.log(skills.includes("CSS")); // true
console.log(skills.indexOf("CSS")); // 1
console.log(skills.slice(0, 1)); // [ 'HTML' ] (a copy of part)
console.log(skills.join(" / ")); // "HTML / CSS"

សូមកត់សម្គាល់ថា push, pop, shift និង unshift ផ្លាស់ប្តូរ array ខ្លួនវាផ្ទាល់។ នេះហៅថា mutation ហើយវាសំខាន់នៅផ្នែកទី 10។ slice, includes និង join មិនផ្លាស់ប្តូរវាទេ។

4. គម្រោងរបស់ Dara ជាទិន្នន័យ

ឥឡូវនេះបញ្ចូលទាំងពីរ។ គម្រោងនីមួយៗជា object ហើយបញ្ជីគម្រោងជា array នៃ object។ នេះជំនួស element <article> ទាំងបួនដែលសរសេរដោយដៃក្នុងស៊េរី HTML & CSS៖ ទិន្នន័យរស់នៅកន្លែងតែមួយ ហើយទំព័រអាចត្រូវបានសង់ពីវា។

បង្កើត projects.js៖

const projects = [
  { id: 1, title: "Recipe Finder", year: 2024, stars: 12, tags: ["html", "css"] },
  { id: 2, title: "Weather Dashboard", year: 2025, stars: 30, tags: ["javascript", "api"] },
  { id: 3, title: "Khmer Typing Game", year: 2025, stars: 8, tags: ["javascript", "css"] },
  { id: 4, title: "Budget Tracker", year: 2023, stars: 21, tags: ["javascript"] },
];

រាល់ object មាន រូបរាង ដូចគ្នា៖ id, title, year, stars និង array tags។ ការរក្សារូបរាងឲ្យស្របគ្នាធ្វើឲ្យកូដដែលតាមក្រោយសាមញ្ញ។ នៅជំពូកទី 11 TypeScript នឹងអនុញ្ញាតឲ្យអ្នកសរសេររូបរាងនោះចុះ ហើយឲ្យកុំព្យូទ័រពិនិត្យវា។

ឧទាហរណ៍ខាងក្រោមទាំងអស់ប្រើ array projects នេះ។

5. ការបំលែង Array៖ map, filter, find

Method ទាំងនេះជំនួស loop ភាគច្រើន។ ម្នាក់ៗទទួល callback (ជំពូកទី 5) ហើយ return លទ្ធផលថ្មី ដោយមិនផ្លាស់ប្តូរ array ដើមទេ។

map បំលែង item នីមួយៗទៅជាអ្វីផ្សេង។ លទ្ធផលមានប្រវែងដូចគ្នា៖

const titles = projects.map((project) => project.title);
console.log(titles);
// [ 'Recipe Finder', 'Weather Dashboard', 'Khmer Typing Game', 'Budget Tracker' ]

filter រក្សាតែ item ដែល callback return true៖

const jsTitles = projects
  .filter((project) => project.tags.includes("javascript"))
  .map((project) => project.title);

console.log(jsTitles);
// [ 'Weather Dashboard', 'Khmer Typing Game', 'Budget Tracker' ]

find return item ដែលត្រូវគ្នា ទីមួយ ឬ undefined ប្រសិនបើគ្មានអ្វីត្រូវគ្នា៖

console.log(projects.find((project) => project.id === 3)?.title);
// "Khmer Typing Game"

console.log(projects.find((project) => project.id === 99));
// undefined

ការភ្ជាប់ filter រួចទៅ map ដូចខាងលើ គឺជាលំនាំដែលអ្នកនឹងប្រើគ្រប់ពេល។ នេះគឺជារបៀបពិតប្រាកដដែលបញ្ជីគម្រោងដែលអាចត្រងបាននៅលើទំព័ររបស់ Dara នឹងជ្រើសរើស item របស់វា។

6. ការត្រួតពិនិត្យ និងការបញ្ចូលគ្នា៖ some, every, reduce, sort

some សួរថា "តើមាន item យ៉ាងហោចណាស់មួយត្រូវគ្នាឬទេ?" ហើយ every សួរថា "តើទាំងអស់ត្រូវគ្នាឬទេ?"។ ទាំងពីរ return boolean៖

console.log(projects.some((project) => project.stars > 25)); // true
console.log(projects.every((project) => project.year >= 2024)); // false

reduce បញ្ចូល item ទាំងអស់ទៅជាតម្លៃតែមួយ។ វាទទួល accumulator ដែលកំពុងរត់ និង item បច្ចុប្បន្ន ហើយចាប់ផ្តើមពីតម្លៃដែលអ្នកផ្តល់ជា argument ទីពីរ៖

const totalStars = projects.reduce((sum, project) => sum + project.stars, 0);
console.log(totalStars); // 71

sort តម្រៀប item តាមលំដាប់។ ប្រយ័ត្ន៖ វា mutate array ហើយបើគ្មាន comparison function វាតម្រៀបជា អក្សរ៖

console.log([10, 9, 1].sort()); // [ 1, 10, 9 ]  (text order!)
console.log([10, 9, 1].sort((a, b) => a - b)); // [ 1, 9, 10 ]

Comparison function return លេខអវិជ្ជមាន ប្រសិនបើ a មកមុន លេខវិជ្ជមាន ប្រសិនបើ b មកមុន និងសូន្យ ប្រសិនបើស្មើគ្នា។ ដើម្បីតម្រៀបដោយមិនផ្លាស់ប្តូរ array ដើម សូមចម្លងវាជាមុនដោយ spread (ផ្នែកបន្ទាប់)៖

const byStars = [...projects].sort((a, b) => b.stars - a.stars);
console.log(byStars.map((project) => project.title));
// [ 'Weather Dashboard', 'Budget Tracker', 'Recipe Finder', 'Khmer Typing Game' ]

សម្រាប់ការតម្រៀបពាក្យ សូមប្រើ a.localeCompare(b) ជំនួសការដក។

MethodReturnផ្លាស់ប្តូរ array ដើមឬទេ?
mapArray ថ្មី ប្រវែងដូចគ្នាទេ
filterArray ថ្មី ខ្លីជាង ឬស្មើទេ
findItem មួយ ឬ undefinedទេ
some / everytrue ឬ falseទេ
reduceតម្លៃមួយនៃប្រភេទណាក៏បានទេ
sortArray ដដែល តម្រៀបឡើងវិញបាទ/ចាស

7. Destructuring, Spread និង Rest

លក្ខណៈពិសេសទាំងបីនេះប្រើ ... និង { } / [ ] ដើម្បីសន្សំការវាយ។

Destructuring ទាញតម្លៃចេញពី object ឬ array ទៅជា variable៖

const { title, year } = projects[0];
console.log(title, year); // "Recipe Finder" 2024

const { stars: starCount, license = "MIT" } = projects[0];
console.log(starCount, license); // 12 "MIT"

const [first, second, ...others] = projects;
console.log(first.id, second.id, others.length); // 1 2 2

អ្នកអាចប្តូរឈ្មោះ property (stars: starCount) និងផ្តល់ default (license = "MIT")។ វាក៏ដំណើរការក្នុង parameter របស់ function ដែរ ដែលជារឿងទូទៅណាស់៖

const printCard = ({ title, year }) => `${title} (${year})`;
console.log(printCard(projects[1])); // "Weather Dashboard (2025)"

Spread (...) ចម្លង item ឬ property នៃរចនាសម្ព័ន្ធមួយទៅក្នុងរចនាសម្ព័ន្ធថ្មី៖

const updated = { ...projects[0], stars: 13 };
console.log(updated.stars, projects[0].stars); // 13 12

const more = [...projects, { id: 5, title: "New", year: 2026, stars: 0, tags: [] }];
console.log(more.length, projects.length); // 5 4

Property ដែលសរសេរក្រោយឈ្នះ ដូច្នេះ stars: 13 ជំនួសតម្លៃដែលបានចម្លង។ នេះជារបៀបដែលអ្នក "ផ្លាស់ប្តូរ" ទិន្នន័យដោយមិន mutate៖ សង់ object ថ្មី។

Rest ប្រើ ... ដូចគ្នានៅម្ខាងទៀត ដើម្បីប្រមូលអ្វីដែលនៅសល់៖

const { tags, ...rest } = projects[0];
console.log(rest); // { id: 1, title: 'Recipe Finder', year: 2024, stars: 12 }

របៀបចងចាំ៖ spread ពង្រាយ រចនាសម្ព័ន្ធចេញជាបំណែកៗ; rest ប្រមូល បំណែកៗចូលជារចនាសម្ព័ន្ធ។

8. Optional Chaining និង Object Helper

ការអាន property របស់ undefined ឬ null បោះកំហុស។ Optional chaining (?.) ឈប់ ហើយផ្តល់ undefined ជំនួស។ ផ្សំវាជាមួយ ?? (ពីជំពូកទី 3) សម្រាប់តម្លៃជំនួស៖

const user = { profile: { address: null } };

console.log(user.profile?.address?.city); // undefined
console.log(user.settings?.theme ?? "light"); // "light"

Helper បីរាយមាតិកាក្នុង object៖

console.log(Object.keys(dara)); // [ 'name', 'city', 'skills' ]
console.log(Object.values(dara).length); // 3

for (const [key, value] of Object.entries({ html: 1, css: 2 })) {
  console.log(key, value);
}
// html 1
// css 2

Object.entries return គូ [key, value] ដែលសមនឹង for...of និង destructuring យ៉ាងល្អ។ នេះជាការជំនួសដ៏សុវត្ថិភាពសម្រាប់ for...in ដែលជំពូកទី 4 បានណែនាំ។

ឧបករណ៍មានប្រយោជន៍មួយទៀត៖ រាប់ tag ទូទាំងគម្រោងទាំងអស់ ដើម្បីសង់ប៊ូតុងត្រងនៅពេលក្រោយ។

const allTags = [...new Set(projects.flatMap((project) => project.tags))];
console.log(allTags); // [ 'html', 'css', 'javascript', 'api' ]

flatMap ភ្ជាប់ array tags របស់គម្រោងនីមួយៗទៅជាបញ្ជីតែមួយ ហើយ Set លុបចោលអ្វីដែលជាន់គ្នា។

9. JSON

JSON (JavaScript Object Notation) គឺជាទម្រង់អត្ថបទសម្រាប់ទិន្នន័យ។ web API ស្ទើរតែទាំងអស់ផ្ញើ និងទទួល JSON ហើយវាមើលទៅដូច object literal ប៉ុន្តែមានច្បាប់តឹងរ៉ឹងជាង៖ key ត្រូវតែប្រើសញ្ញាសម្រង់ពីរ ហើយតម្លៃអាចជាតែ string, number, boolean, null, array ឬ object ប៉ុណ្ណោះ។ គ្មាន function គ្មាន undefined។

Function ពីរបំលែងរវាងតម្លៃ JavaScript និងអត្ថបទ JSON៖

const json = JSON.stringify(projects[0]);
console.log(json);
// {"id":1,"title":"Recipe Finder","year":2024,"stars":12,"tags":["html","css"]}

const back = JSON.parse(json);
console.log(back.tags); // [ 'html', 'css' ]

JSON.stringify(value, null, 2) បន្ថែមការចូលបន្ទាត់ ដែលងាយអានជាង។ ចងចាំទិសដៅទាំងពីរនេះ៖

  • stringify: តម្លៃ JavaScript ទៅអត្ថបទ (ដើម្បីផ្ញើ ឬរក្សាទុក)។
  • parse: អត្ថបទទៅតម្លៃ JavaScript (បន្ទាប់ពីអ្នកទទួលបាន)។ ប្រសិនបើអត្ថបទមិនមែនជា JSON ត្រឹមត្រូវ parse បោះកំហុស; ជំពូកទី 10 បង្ហាញរបៀបដោះស្រាយវា។

នៅជំពូកទី 9 GitHub API នឹងផ្ញើ repository របស់ Dara ជា JSON ហើយ fetch នឹង parse វាឲ្យអ្នក។

10. ចម្លង ទល់នឹង យោង

Number និង string ត្រូវបានចម្លងនៅពេលអ្នកកំណត់ឲ្យវា។ Array និង object មិនមែនទេ៖ variable ផ្ទុក reference ដូចជាអាសយដ្ឋាន ទៅកាន់ទិន្នន័យ។

const a = { n: 1 };
const b = a; // b points to the SAME object

b.n = 2;
console.log(a.n); // 2

ការផ្លាស់ប្តូរ b បានផ្លាស់ប្តូរ a ព្រោះវាជា object តែមួយ។ នេះក៏មានន័យថា object ពីរដាច់ដោយឡែកមិនដែលស្មើគ្នាទេ សូម្បីមាតិកាដូចគ្នាបេះបិទ៖

console.log({} === {}); // false
console.log([1] === [1]); // false

Spread បង្កើត shallow copy៖ កម្រិតកំពូលគឺថ្មី ប៉ុន្តែ object និង array ដែលដាក់ក្នុងគ្នានៅតែត្រូវបានចែករំលែក។

const copy = { ...projects[0] };
copy.tags.push("x"); // changes the nested array

console.log(projects[0].tags); // [ 'html', 'css', 'x' ]

ដើម្បីចម្លងអ្វីៗទាំងអស់ រួមទាំងទិន្នន័យដែលដាក់ក្នុងគ្នា សូមប្រើ structuredClone៖

projects[0].tags.pop(); // undo the accidental change

const deep = structuredClone(projects[0]);
deep.tags.push("y");

console.log(projects[0].tags); // [ 'html', 'css' ]
console.log(deep.tags); // [ 'html', 'css', 'y' ]

ដំបូន្មានជាក់ស្តែង៖ ពេញចិត្ត method ដែល return តម្លៃថ្មី (map, filter, spread) ជាងអ្វីដែល mutate (push, sort) ជាពិសេសសម្រាប់ទិន្នន័យដែលទំព័របង្ហាញ។ វាធ្វើឲ្យការរក bug ងាយស្រួលជាងច្រើន។

11. សាកល្បងដោយខ្លួនឯង

  1. សង់បញ្ជីផ្ទាល់ខ្លួន។ បង្កើត object ពិពណ៌នាខ្លួនអ្នក ដែលមាន name, city និង array skills។ បោះពុម្ពជំនាញនីមួយៗដោយ for...of រួចបន្ថែមជំនាញមួយដោយ push។
  2. បន្ថែមគម្រោង។ បន្ថែមគម្រោងទីប្រាំទៅ array projects ជាមួយចំណងជើង និង tag របស់អ្នក។ តើ method ណាខ្លះក្នុងផ្នែកទី 5 នៅតែដំណើរការដោយមិនចាំបាច់ផ្លាស់ប្តូរ?
  3. ត្រង និងតម្រៀប។ បង្ហាញចំណងជើងគម្រោងពីឆ្នាំ 2025 ឬក្រោយនោះ តម្រៀបតាម stars ពីខ្ពស់ទៅទាប ដោយមិនផ្លាស់ប្តូរ projects។
  4. រកមធ្យមភាគ។ ប្រើ reduce ដើម្បីគណនាចំនួន stars មធ្យម។ បន្ទាប់មកប្រើ some ដើម្បីពិនិត្យថាតើមានគម្រោងណាមួយមាន stars សូន្យឬទេ។
  5. Destructure។ សរសេរ function summary({ title, stars, tags }) ដែល return string ដូចជា Weather Dashboard: 30 stars, 2 tags។
  6. JSON ទៅមកវិញ។ បំលែង projects ទៅជាអត្ថបទ JSON រួច parse វាត្រឡប់មកវិញ។ តើលទ្ធផល === នឹង array ដើមឬទេ? ពន្យល់ថាហេតុអ្វីបាន ឬមិនបាន។ បន្ទាប់មកសាកល្បង JSON.parse("{ title: 'x' }") ហើយអានកំហុស។

បន្ទាប់ យើងនឹងបំបែកកូដទៅជាឯកសារដាច់ដោយឡែកដោយ module ហើយស្គាល់ Node និង npm ជាឧបករណ៍ដែលដំណើរការ និងគ្រប់គ្រងគម្រោង JavaScript របស់អ្នក។

ទិញកាហ្វេជូនខ្ញុំ

ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!