ICSI301 Төсөл 2: ЖаваСкрипт дасгал

Тохиргоо

Хэдийгээр энэ төслийг өөрийн веб хөтөч дээрээ ажиллуулж болох ч гэсэн таны үйлдлийн системд Node.js суусан байх хэрэгтэй. Энэ програмыг ашиглан кодын чанарыг шалгах юм. Хэрэв суулгаагүй бол Node.js болон npm модуль менежер програмыг зааврын дагуу одоо суулгаарай.

Node.js суулгасны дараа project2 нэртэй хавтас үүсгээд энэ zip файлыг дотор нь задлаарай. Энэ zip файлд cs142-test-project2.html болон cs142-test-project2.js файлууд байх бөгөөд эдгээрийг ашиглаад төслийн кодоо тестлэх фрэймвөрк маягаар ашиглах юм.

Та кодын чанарыг шалгадаг багаж ("linter" гэж нэрлэдэг), ESLint багажийг татаж аваад project2 хавтас дотроос дараах командаар ажиллуулна:

npm install

Энэ нь ESLint багажийг node_modules дэд хавтас дотор татаж авна. Та project2 хавтас дотор байгаа бүх ЖаваСкрипт файлууд үүнийг ажиллуулах боломжтой болох юм. Дараах командаар кодынхоо чанарыг шалгаарай:

npm run lint

Таны илгээх бүх ЖаваСкрипт файлын код чинь 'use strict'; мөрөөр эхлэх ёстой. Мөн ESLint програмаар шалгахад ямар нэг алдаа эсвэл санамж (warning) байх ёсгүй юм шүү. Ямар нэг алдаа эсвэл санамжтай бол загварын онооноос хасагдах болно.

Энэ даалгаварыг ажиллуулахад танд хоёр сонголт байна:

  1. Өөрийн веб хөтөч дээр: cs142-test-project2.html файлыг шууд нээж ажиллуулах. Энэ веб хуудас нь таны бичсэн ЖаваСкрипт файлыг ажиллуулах бөгөөд хэд хэдэн тестийг ажиллуулж үр дүнг харуулна.
  2. Node.js дээр: Та тестийг веб хөтөчгүйгээр ажиллуулах. Дараах командыг ажиллуулаарай.
    npm test

Бид хөгжүүлэлтийн үед веб хөтчийг ашиглахыг санал болгож байна. Энэ нь програмаа алхам бүрээр ажиллуулж үр дүнг нь харахад (debugging) илүү дээр. Гэсэн хэдий ч бид таны төслийг үнэлэхдээ Node.js ашиглана.

Санамж: Эдгээр тестүүд нь бүх нөхцлийг тооцоогүй. Эдгээр нь та үндсэн кодоо бичиж дуусмагц програм бүхэлдээ яаж ажилладагийг зааварчилж таниулах болно. Бидний өгсөн файлд байгаа тестүүд даалгаварт өгсөн тодорхойлолтуудыг бүгдийг бүрэн тестлээгүй учир тодорхойлолтын дагуу бүрэн хэрэгжүүлэх эсэх нь таны хариуцах ажил юм шүү.

Энэ төслөөр хэд хэдэн ЖаваСкрипт функц бичнэ. Энэ бие даалтаар өгч буй даалгаваруудаар хөгжүүлэх бодит практик болон функцүүд нь хичээлийн бусад төслүүдэд дараа хэрэг болно. Өгсөн ЖаваСкриптийн ямар даалгаврыг гүйцэтгэхэд шаардлагатай ЖаваСкриптийн зарим стандарт функцүүдийг хэдэн мөрөнд ашиглаж болно. Энэ төслийн зорилго нь ЖаваСкриптийг сурахад чиглэж байгаа тул ЖаваСкриптийн бусад бэлэн санг ашиглахыг зөвшөөрөхгүй. Зөвхөн ЖаваСкриптийн өөрийнх нь функцүүдийг (built-in), жишээ нь, Arrays, Date Objects гэх мэт, ашиглахыг зөвшөөрнө.

Даалгавар 1: Олон шүүлтүүрт функцийг үүсгэх (10 оноо)

project2 хавтас дотроо cs142-make-multi-filter.js нэртэй шинэ файл үүсгэнэ. Таны үүсгэх Олон шүүлтүүрт функцийн код энэ файлд байна.

cs142MakeMultiFilter нэртэй гадаад функц тодорхойлно. Энэ нь нэг хүснэгтэн хувьсагч (originalArray) параметртээ авч тухайн хүснэгтэн хувьсагчийн элементүүдийг шүүж гаргахад хэрэглэх нэг функц буцаадаг байна. Буцааж буй (arrayFilterer) функц нь дотроо currentArray гэж нэрлэх хувьсагчид шүүгдэж үлдсэн элементүүдийг хадгалж явдаг байх юм. Эхэндээ currentArray нь originalArray хувьсагчтай ижил утгатай байна. arrayFilterer функц нь хоёр функцийг параметртээ авна. Үүнд:

  1. filterCriteria - Энэ функц параметртээ нэг хүснэгтэн хувьсагчийг авч boolean утга буцаадаг. Энэ функц currentArray хувьсагчийн элемент бүрийн хувьд дуудагдах бөгөөд currentArray нь filterCriteria функцийн үр дүнд шинэчлэгддэг байна. Хэрэв filterCriteria функц тухайн элементийн хувьд false утга буцаавал тэр элемент currentArray хувьсагчаас хасагдана. Эсрэг тохиолдолд тухайн элемент нь currentArray хувьсагчдаа үлдэнэ. Хэрэв filterCriteria функц биш байвал буцааж буй (arrayFilterer) функц currentArray хувьсагчийн утгыг ямар нэг шүүлт хийлгүйгээр шууд буцаадаг байна.
  2. callback - Энэ функц нь шүүлт хийгдэж дуусмагц дуудагддаг. callback нь currentArray хувьсагчийн утгыг аргументдээ авдаг. callback функц дотроос this хувьсагчаар хандахад originalArray хувьсагчийн утгыг заадаг байх ёстой. Хэрэв callback функц биш бол үүнийг дуудахгүй. callback нь ямар нэг утга буцаахгүй.
arrayFilterer функц нь filterCriteria параметр тодорхойлогдоогүй, currentArray хувьсагчийг буцаагаагүй бусад нөхцөлд өөрийгөө буцаадаг байна. Энэ нь arrayFilterer функцийг нэг агшинд олон удаа ажиллуулах боломжийг олгодог байна.

Дараах кодоор таны тодорхойлсон функцийг хэрхэн ашиглаж болохыг харууллаа:

// cs142MakeMultiFilter() функцийг originalArray = [1, 2, 3] параметртэйгээ дуудахад нэг функц буцаана, 
// энэ нь arrayFilterer1 хувьсагчид хадгалагдана, үүнийг олон давтамжтай дуудаж
// оролтын хүснэгтэн хувьсагчийн элементийг шүүнэ.
var arrayFilterer1 = cs142MakeMultiFilter([1, 2, 3]);

// arrayFilterer1 функцийг (callback функц өгч) дуудаад 2-той тэнцүү биш утгуудыг
// шүүнэ.
arrayFilterer1(function (elem) {
  return elem !== 2; // элемент 2-той тэнцүү биш эсэхийг шалгах
}, function (currentArray) {
  // callback функц доторх 'this' хувьсагч [1, 2, 3] утгатай originalArray-г заана.
  console.log(this); // [1, 2, 3] гэж дэлгэцлэнэ
  console.log(currentArray); // [1, 3] гэж дэлгэцлэнэ
});

// arrayFilterer1 функцийг (callback функцгүй) дуудахад 3-тай тэнцүү биш
// утгуудыг шүүнэ.
arrayFilterer1(function (elem) {
  return elem !== 3; // элемент 3-тай тэнцүү биш эсэхийг шалгах
});

// arrayFilterer1 функцийг filterCriteria параметргүй дуудахад currentArray-г буцаана.
var currentArray = arrayFilterer1();
console.log('currentArray', currentArray); // [1] гэж дэлгэцлэнэ. Учир нь 2 болон 3 утгууд хасагдсан.

// arrayFilterer өөрийгөө буцаадаг тул, ар араас нь гинжилж дуудаж болно.
function filterTwos(elem) { return elem !== 2; }
function filterThrees(elem) { return elem !== 3; }
var arrayFilterer2 = cs142MakeMultiFilter([1, 2, 3]);
var currentArray2 = arrayFilterer2(filterTwos)(filterThrees)();
console.log('currentArray2', currentArray2); // [1] гэж дэлгэцлэнэ. Учир нь 2 болон 3 утгууд хасагдсан.

// Олон шүүлтүүрт функцийг нэг агшинд олон удаа нь хэрэглэнэ.
var arrayFilterer3 = cs142MakeMultiFilter([1, 2, 3]);
var arrayFilterer4 = cs142MakeMultiFilter([4, 5, 6]);
console.log(arrayFilterer3(filterTwos)()); // [1, 3] дэлгэцлэнэ
console.log(arrayFilterer4(filterThrees)()); // [4, 5, 6] дэлгэцлэнэ

Даалгавар 2: Загвар процессор (5 оноо)

project2 хавтас дотроо cs142-template-processor.js нэрээр нэг файл үүсгэнэ. Загвар процессорын код энэ файлд байх ёстой.

Нэг Загвар процессор класс үүсгэнэ (cs142TemplateProcessor). Энэ нь нэг string (тэмдэгт мөр) төрлийн template параметр авдаг байгуулагчтай, fillIn нэртэй нэг методтой байна. Энэ fillIn методыг dictionary объект өгч дуудахад тэмдэгт мөр буцаах бөгөөд энэ утгыг dictionary объектын утгуудаар загварыг (template) дүүргэсэн байна. cs142TemplateProcessor классыг ЖаваСкриптын стандарт байгуулагч болон prototype бүтцийг ашиглан бичнэ.

fillIn метод template тэмдэгт мөрийг буцаах ба {{property}} (шинж) хэлбэртэй/форматтай ямар ч бичвэрийг методод дамжуулж өгсөн dictionary объектын харгалзах property утгуудаар сольдог байна.

Хэрэв загвар нь dictionary объектод байхгүй шинжийг агуулж байвал тэр шинж байх газар хоосон тэмдэгтээр солино. Хэрэв шинж нь хоёр үгийн хооронд байрласан бол хоёр хоосон зай харагдах болно. Жишээ нь: "This {{undefinedProperty}} is cool""This is cool". Энэ бол байж болно. Та нэмэлт хоосон зайг яах талаар санаа зовох хэрэггүй.

Таны систем зөвхөн зөв форматтай шинжийг л авч үздэг байна. Магадгүй энэ нь дараах тохиолдолд, бид нэг бүрчлэн шалгаагүй учир undefined байж болзошгүй.

  • давхарлагдсан шинжүүд - {{foo {{bar}}}} эсвэл {{{{bar}}}} эсвэл {{{bar}}}
  • ижил биш уян хаалт - {{bar}}}
  • шинжийн нэрэнд байх уян хаалт - da{y or da}y

Дараах кодоор энэ даалгавраар тодорхойлж буй функцүүдийг хэрхэн ашиглаж болохыг харууллаа:

var template = 'My favorite month is {{month}} but not the day {{day}} or the year {{year}}';
var dateTemplate = new cs142TemplateProcessor(template);

var dictionary = {month: 'July', day: '1', year: '2016'};
var str = dateTemplate.fillIn(dictionary);

assert(str === 'My favorite month is July but not the day 1 or the year 2016');

//тохиолдол: шинж dictionary объектод байхгүй байх
var dictionary2 = {day: '1', year: '2016'};
var str = dateTemplate.fillIn(dictionary2);

assert(str === 'My favorite month is  but not the day 1 or the year 2016');

Даалгавар 3: cs142-test-project2.js кодыг засаж гадаад орчныг (global namespace) бохирдуулахгүй болгох (5 оноо)

Бидний өгсөн тестийн ЖаваСкрипт файл (cs142-test-project2.js) нь нэлээд олон хувьсагчийг ЖаваСкриптийн гадаад орчинд зарласан байгаа. Жишээ нь, энэ файлыг дуудахад p1Message хувьсагч гадаад орчинд харагдана. Иймд өөр нэг ЖаваСкрипт файлаас p1Message энэ хувьсагчид хандах боломжтой гэсэн үг. cs142-test-project2.js файлын кодыг ЖаваСкриптийн стандарт модулийн anonymous function ашигладаг загвараар гадаад орчинд байх хувьсагчуудыг нуудаг, бас таны бичсэн кодууд өмнөх шиг шалгаж болдог байхаар өөрчилнө.

Загварын оноо (5 оноо)

Энэ оноог таны бичсэн ЖаваСкрипт код цэвэрхэн, уншууртай, ESLint санамжгүй тохиолдолд өгнө.

Зөвлөмж

  • ЖаваСкрипт хэлэнд тэнцүү/тэнцүү бишийг шалгахад == болон != операторуудын оронд === болон !== операторыг ашиглаарай.
  • ESLint програмыг ажиллуулах үед .eslintrc.json (нуугдмал файл) байгаа эсэхийг шалгаарай. Үгүй бол ESLint алдаа өгнө. ls -a (dir /a Виндоус дээр) командын мөрөөр тухайн хавтас дотор байгаа бүх файлыг, нуугдмал файлыг ч харж болно.
  • Хэрэв ESLint олон тооны загварыг асуудлуудыг гаргавал npm run lint -- --fix командаар ихэнхийг нь засах боломжтой.
  • Файлуудаа хуулахдаа командын мөрийг ашиглаарай. Чирээд хуулах нь ихэвчлэн нуугдмал файлыг хуулдаггүй нь zip файлд орох ёстой .eslintrc.json файлгүйгээр илгээх нөхцлийг үүсгэдэг.
  • Даалгавар 1-д үзүүлсэн шаардлага cs142MakeMultiFilter функцийг нэгэн зэрэг олон удаа ашиглах тул currentArray хувьсагчийг гадаад орчинд хадгалахгүй байх ёстой.
  • Даалгавар 3-т, зөвхөн тест файлд байгаа хувьсагчуудтай л ажилла. Бас cs142Project2Results хувьсагчийг гадаад орчинд нь (жишээ нь, window объектын шинжээр) үлдээх ёстой. Ийм байж run-tests-using-node.js скриптыг ажиллуулж болно.
  • Даалгавар 1-ийн хувьд:
    - ЖаваСкрипт функц, closure, callback функц, function prototype, this хувьсагч зэргийг онцгойлон судлах
    - Бичих функцыг чинь яаж ашиглаж байгаа кодыг сайтар ойлгох, console.log ашиглан debug хийж үзэх
  • Даалгавар 2-ийн хувьд: объект, класс, класс тодорхойлох функцийн арга, прототайп, string, regular expression зэргийг зайлшгүй судлах бичвэр дотор өгөгдөх паттерн, жишээ нь, {{month}} нь дурын паттерн байж болохоор хийх
  • Даалгавар 3-ийн хувьд:
    - global болон local хувьсагчийн үйчлэх хүрээ, anonymous function, immediately invoked function expression (IIFE) бичиглэл зэргийг тусгайлан үзэх
    - ЖаваСкрипт програмын модуль хэрхэн бичдэгийг ойлгох
  • Нийтлэг зөвлөмж:
    - Зөвхөн өөрөө бодож, шийдэл боловсруулж, хичээл зүтгэлээр хийх
    - Интернэтээс эсвэл бусдаас бэлэн шийдэл, энэ даалгаварыг хийсэн код харахгүй байх (ингэвэл өөрөө сэтгэхээ больдог шүү)
    - Өөрийн хэрэгжүүлсэн код бүрийг тайлбарладаг байх нь чухал

Илгээх

Даалгаврыг илгээхдээ project2 нэртэй хавтас дотор cs142-make-multi-filter.js, cs142-template-processor.js, cs142-test-project2.js, болон cs142-test-project2.html файлуудыг оруулсан байна. Эдгээр файлуудад npm run lint болон npm test командуудыг ажиллуулсан байх ба ямар нэг алдаа, санамжгүй болсон байх ёстой.