Библиотеки чрез затваряния в JavaScript
Често в JavaScript се създават библиотеки, които представляват колекции от функции за използване от други програмисти.
Такива библиотеки обикновено се опаковат в модули чрез затваряния. Това се прави, така че при свързване на библиотеката във външния свят да се появяват възможно най-малко функции.
Като правило всяка библиотека се стреми да създава във външния свят само една променлива - обект с функциите на библиотеката. В същото време вътре в кода на библиотеката част от функциите са основни, а част - спомагателни. Очевидно е, че във външния свят искаме да експортираме само необходимите функции, без да затрупваме експортирания обект със спомагателни функции.
Нека разгледаме пример. Да предположим, че имаме следния набор от функции, които бихме искали да превърнем в библиотека:
function square(num) {
return num ** 2;
}
function cube(num) {
return num ** 3;
}
function avg(arr) {
return sum(arr, 1) / arr.length;
}
function digitsSum(num) {
return sum(String(num).split(''));
}
// спомагателна функция
function sum(arr) {
let res = 0;
for (let elem of arr) {
res += +elem;
}
return res;
}
Нека оформим нашите функции като модул:
;(function() {
function square(num) {
return num ** 2;
}
function cube(num) {
return num ** 3;
}
function avg(arr) {
return sum(arr, 1) / arr.length;
}
function digitsSum(num) {
return sum(String(num).split(''));
}
// спомагателна функция
function sum(arr) {
let res = 0;
for (let elem of arr) {
res += +elem;
}
return res;
}
})();
А сега нека експортираме всички функции, с изключение на спомагателната:
;(function() {
function square(num) {
return num ** 2;
}
function cube(num) {
return num ** 3;
}
function avg(arr) {
return sum(arr, 1) / arr.length;
}
function digitsSum(num) {
return sum(String(num).split(''));
}
// спомагателна функция
function sum(arr) {
let res = 0;
for (let elem of arr) {
res += +elem;
}
return res;
}
window.math = {square, cube, avg, digitsSum};
})();
Да предположим, че имаме HTML страница index.html:
<html>
<head>
<script>
</script>
</head>
</html>
Нека свържем нашата библиотека с нея:
<html>
<head>
<script src="math.js"></script>
<script>
</script>
</head>
</html>
Нека използваме функциите от нашата библиотека:
<html>
<head>
<script src="math.js"></script>
<script>
alert(math.avg([1, 2, 3]) + math.square());
</script>
</head>
</html>
Даден е следният код:
function avg1(arr) {
return sum(arr, 1) / arr.length;
}
function avg2(arr) {
return sum(arr, 2) / arr.length;
}
function avg3(arr) {
return sum(arr, 3) / arr.length;
}
// спомагателна функция
function sum(arr, pow) {
let res = 0;
for (let elem of arr) {
res += elem ** pow;
}
return res;
}
Оформете този код като модул. Експортирайте навън всички функции, с изключение на спомагателната.
Изучете библиотеката underscore.
Направете ваша собствена аналогична библиотека, като повторите
в нея 5-10 функции от оригиналната
библиотека.