JavaScript-də arifmetik əməliyyatlar. Arifmetik operatorlar Əlifba sırası ilə çeşidləyin




Üstünlük, assosiativlik və digər ikinci dərəcəli məsələlər haqqında danışdıqdan sonra operatorların özlərini müzakirə etməyə başlaya bilərik. Bu bölmə arifmetik operatorların təsvirini təqdim edir:

Əlavə (+)
Plyus operatoru rəqəmli operandları əlavə edir və ya sətir birləşməsini həyata keçirir. Operandlardan biri sətirdirsə, digər operand sətirə çevrilir və birləşdirilir. Obyektlərin operandları əlavə və ya birləşdirilə bilən rəqəmlərə və ya sətirlərə çevrilir. Dönüşüm valueOf() və/və ya toString() metodlarından istifadə etməklə həyata keçirilir.

Çıxarma (−)
İkili operator kimi "minus" istifadə edildikdə, birincidən ikinci operandı çıxarır. Əgər qeyri-rəqəm operandları göstərilibsə, o, onları rəqəmlərə çevirməyə çalışır.

Vurma (*)
* operatoru iki operandını çoxaldır. Rəqəmsiz operandları ədədlərə çevirməyə çalışır.

Bölmə (/)
/ operatoru birinci operandı ikinciyə bölür. Rəqəmsiz operandları ədədlərə çevirməyə çalışır. Tam ədədlərlə həqiqi ədədləri fərqləndirən proqramlaşdırma dillərinə öyrəşmiş insanlar bir tam ədədi digərinə böldükdə tam nəticə əldə etməyi gözləyə bilərlər.

Bununla belə, JavaScript-də bütün rəqəmlər realdır, buna görə də bütün bölmələr üzən nöqtədir. 5/2 əməliyyatı 2 deyil, 2.5 verir. Sıfıra bölmək nəticədə sonsuzluğa artı və ya dəqiqə verir, 0/0 isə NaN verir.

Modul (%)
% operatoru birinci operandın ikinciyə tam bölünməsinin qalığını hesablayır. Əgər qeyri-rəqəm operandları verilirsə, operator onları ədədlərə çevirməyə çalışır. Nəticənin işarəsi birinci operandın işarəsi ilə eynidir. Məsələn, 5% 2 1 verir.
Modul operatoru adətən tam operandlarla istifadə olunur, lakin real dəyərlər üçün də işləyir. Məsələn, -4,3 % 2,1 -0,1 ilə nəticələnir.

Birlik mənfi (-)
Minus tək operanddan əvvəl unar operator kimi istifadə edildikdə, o, unar işarə dəyişdirmə əməliyyatını yerinə yetirir. Başqa sözlə, müsbət dəyəri mənfi dəyərə çevirir və əksinə. Operand rəqəm deyilsə, bu operator onu nömrəyə çevirməyə çalışır.

Tək üstəgəl (+)
Birlik minus operatoru ilə simmetriya üçün JavaScript-də birlik artı operatoru da var. Proqram mətnini daha başa düşülən edəcəyini düşünürsünüzsə, bu operatorla rəqəmsal hərflərin işarəsini açıq şəkildə təyin edə bilərsiniz:
var mənfəət = +1000000;

Belə kodda plus operatoru heç nə etmir; onun fəaliyyətinin nəticəsi onun arqumentinin dəyəridir.

Bununla belə, qeyri-rəqəmli arqumentləri rəqəmlərə çevirir. Arqument çevrilə bilmirsə, NaN qaytarılır.

Artırma (++)
Bu operator dəyişən, massiv elementi və ya obyektin xassəsi olmalı olan yeganə operandını artırır (yəni bir artır). Əgər həmin dəyişənin, massiv elementinin və ya xassəsinin qiyməti ədəd deyilsə, operator əvvəlcə onu ədədə çevirməyə çalışır. Bu operatorun dəqiq davranışı onun operandla bağlı mövqeyindən asılıdır. Əgər onu operandın (prefiksin artım operatoru) önünə qoysanız, operanda 1 əlavə edilir və nəticə operandın artan qiyməti olur. Əgər o, operanddan sonra yerləşdirilirsə (postfiks artım operatoru), onda operanda 1 əlavə edilir, lakin nəticə operandın orijinal qiymətidir. Artırılan dəyər rəqəm deyilsə, hesablama zamanı o rəqəmə çevrilir.

Məsələn, aşağıdakı kod i və j dəyişənlərini 2-yə təyin edir:
i = 1;
j = ++i;
Bu, i-ni 2-yə və j-i 1-ə təyin edir:
i = 1;
j = i++;

Bu ifadə, hər iki formada, döngəni idarə edən sayğacın artırılması üçün ən çox istifadə olunur.

Nəzərə alın ki, siz prefiks və ya postfiks artım operatoru ilə ondan əvvəlki operand arasında yeni sətir daxil edə bilməzsiniz, çünki JavaScript-də nöqtəli vergüllər avtomatik olaraq daxil edilir. Bunu etsəniz, JavaScript operanda tam təlimat kimi baxacaq və ondan sonra nöqtəli vergül qoyacaq.

Azaltma (−−)
Bu operator dəyişən, massiv elementi və ya obyekt xassəsi ola bilən yeganə ədədi operandını azaldır (yəni 1 azaldır). Bu dəyişənin, elementin və ya xassənin qiyməti ədəd deyilsə, operator əvvəlcə onu ədədə çevirməyə çalışır. ++ operatorunda olduğu kimi, - operatorunun dəqiq davranışı onun operanda nisbətən mövqeyindən asılıdır. Operandın qarşısına qoyulduqda operand azalır və azalmış dəyəri qaytarır. Operanddan sonra o, operandı azaldır, lakin orijinal dəyəri qaytarır.

Çox vaxt JavaScript-də hesablamalar tam olaraq istədiyimiz nəticələri vermir. Əlbəttə ki, biz rəqəmlərlə hər şeyi edə bilərik - yuxarı və ya aşağı yuvarlaqlaşdırın, diapazonlar təyin edin, lazımsız nömrələri müəyyən sayda onluq yerlərə kəsin, hamısı gələcəkdə bu nömrə ilə nə etmək istədiyinizdən asılıdır.

Yuvarlaqlaşdırma niyə lazımdır?

JavaScript-in maraqlı tərəflərindən biri odur ki, o, əslində tam ədədləri saxlamır, biz dərhal üzən nöqtə nömrələri ilə işləyirik. Bu, bir çox fraksiya dəyərinin sonlu sayda onluq yerlərlə ifadə edilə bilməməsi ilə birlikdə, JavaScript-də belə nəticələr əldə edə bilərik:

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
Praktik məqsədlər üçün bu qeyri-dəqiqliyin əhəmiyyəti yoxdur, bizim vəziyyətimizdə kvintilyon səhmlərdəki səhvdən danışırıq, lakin bu, kimisə məyus edə bilər. Valyutaları, faizləri və ya fayl ölçülərini təmsil edən rəqəmlərlə işləyərkən də qəribə nəticələr əldə edə bilərik. Bu qeyri-dəqiqlikləri düzəltmək üçün sadəcə nəticələri yuvarlaqlaşdıra bilməliyik və ondalıq dəqiqliyi təyin etmək kifayətdir.

Ədədlərin yuvarlaqlaşdırılması praktiki istifadəyə malikdir, biz müəyyən diapazondakı nömrə ilə manipulyasiya edə bilərik, məsələn, biz yalnız onluq hissə ilə işləmək əvəzinə dəyəri ən yaxın tam ədədə yuvarlaqlaşdırmaq istəyirik.

Onluqların yuvarlaqlaşdırılması

Onluq ədədi kəsmək üçün toFixed və ya toPrecision metodundan istifadə edin. Onların hər ikisi bir arqument götürür, nəticədə müvafiq olaraq neçə əhəmiyyətli rəqəm (yəni nömrədə istifadə olunan rəqəmlərin ümumi sayı) və ya onluq yerləri (onluq nöqtədən sonrakı rəqəm) müəyyən edir:
  1. Əgər arqument toFixed() üçün təyin olunmayıbsa, o, defolt olaraq sıfır olacaq, yəni 0 onluq yer, arqumentin maksimum dəyəri 20-dir.
  2. Əgər toPrecision-a heç bir arqument verilmirsə, nömrə toxunulmaz qalır
randNum = 6.25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" randNum = 87.335; randNum.toFixed(2); > "87.33" randNum = 87.337; randNum.toPrecision(3); > "87.3"
Həm toFixed() həm də toPrecision() metodları nəticənin rəqəmi deyil, sətir təsvirini qaytarır. Bu o deməkdir ki, yuvarlaqlaşdırılmış dəyəri randNum ilə cəmləyərkən nömrələr deyil, sətirlər birləşdiriləcək:

RandNum = 6.25; let rounded = randNum.toFixed(); // "6" console.log(randNum + dairəvi); > "6.256"
Nəticənin rəqəmsal məlumat tipli olmasını istəyirsinizsə, onda parseFloat istifadə etməlisiniz:

RandNum = 6.25; yuvarlaqlaşdırılsın = parseFloat(randNum.toFixed(1)); konsol jurnalı (yuvarlaqlaşdırılmış); > 6.3
Qeyd edək ki, nadir hallar istisna olmaqla, 5 dəyər yuvarlaqlaşdırılır.

toFixed() və toPrecision() metodları faydalıdır, çünki onlar yalnız fraksiya hissəsini kəsə bilməz, həm də valyutalarla işləyərkən rahat olan onluq yerləri doldura bilər:

TamNum = 1 olsun dollarsCents = totalNum.toFixed(2); console.log(dollarscents); > "1.00"
Qeyd edək ki, tam ədədlərin sayı dəqiqliyin özündən çox olarsa, toPrecision nəticəni eksponensial notasiyada qaytaracaq:

Qoy ədəd = 123.435 ədəd.toPrecision(2); > "1.2e+2"

Ondalıklarla yuvarlaqlaşdırma xətalarından necə qaçınmaq olar

Bəzi hallarda, toFixed və toPrecision 5 dəyərini aşağı və yuxarı yuvarlaqlaşdıracaq:

Qoy numTest = 1.005; numTest.toFixed(2); > "1.00"
Yuxarıdakı hesablamanın nəticəsi 1 yox, 1.01 olmalıdır. Bu cür xətadan qaçmaq istəyirsinizsə, hesablama üçün eksponensial ədədlərdən istifadə edən Jack L Moore tərəfindən təklif olunan həll yolu istifadə edə bilərik:

Funksiya dəyirmi(dəyər, onluq) ( qaytarın Ədəd(Math.round(dəyər+"e"+onluqlar)+"e-"+onluqlar); )
İndi:

Dəyirmi(1.005,2); > 1.01
Əgər yuxarıda göstəriləndən daha möhkəm həll istəyirsinizsə, MDN-ə müraciət edə bilərsiniz.

Maşın epsilon yuvarlaqlaşdırma

Onluq ədədlərin yuvarlaqlaşdırılması üçün alternativ üsul ES6-da təqdim edilmişdir. Maşın epsilon yuvarlaqlaşdırılması iki üzən nöqtə rəqəmini müqayisə edərkən ağlabatan səhv marjası təmin edir. Yuvarlaqlaşdırma olmadan, müqayisələr aşağıdakılara oxşar nəticələr verə bilər:

0,1 + 0,2 === 0,3 > yanlış
Biz düzgün müqayisəni əldə etmək üçün funksiyamızda Math.EPSİLON-dan istifadə edirik:

epsEqu(x, y) funksiyası ( Math.abs(x - y) qaytarın< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
Funksiya iki arqument qəbul edir: birincisi cari hesablama, ikincisi gözlənilən nəticədir. İkisinin müqayisəsini qaytarır:

EpsEqu(0.1 + 0.2, 0.3) > doğrudur
Bütün müasir brauzerlər artıq ES6 riyaziyyat funksiyalarını dəstəkləyir, lakin IE 11 kimi brauzerlərdə dəstək istəyirsinizsə, polyfills istifadə edin.

Fraksiyalı kəsmə

Yuxarıda göstərilən bütün üsullar onluq ədədlərə yuvarlaqlaşdırıla bilər. Bir ədədi sadəcə iki onluq yerə kəsmək üçün əvvəlcə onu 100-ə vurmalı, sonra nəticəni 100-ə bölmək lazımdır:

Funksiya kəsildi(num) ( qaytarın Math.trunc(num * 100) / 100; ) kəsildi(3.1416) > 3.14
Əgər metodu istənilən sayda onluq yerlərə uyğunlaşdırmaq istəyirsinizsə, bitwise ikiqat inkardan istifadə edə bilərsiniz:

Funksiya kəsildi(num, decimalPlaces) ( qoy numPowerConverter = Math.pow(10, decimalPlaces); qaytarın ~~(num * numPowerConverter)/numPowerConverter; )
İndi:

Qoy randInt = 35,874993; kəsilmiş(randInt,3); > 35.874

Ən yaxın nömrəyə yuvarlaqlaşdırma

Onluq ədədi yuxarı və ya aşağı yuvarlaqlaşdırmaq üçün, ən yaxın olduğumuzdan asılı olaraq, Math.round() istifadə edin:

Math.round(4.3) > 4 Math.round(4.5) > 5
Qeyd edək ki, "qiymətin yarısı", 0,5 riyaziyyat qaydaları ilə yuvarlaqlaşdırılır.

Ən yaxın tam ədədə yuvarlaqlaşdırma

Həmişə aşağı yuvarlaqlaşdırmaq istəyirsinizsə, Math.floor-dan istifadə edin:

Math.floor(42.23); > 42 Math.floor(36.93); > 36
Nəzərə alın ki, yuvarlaqlaşdırma bütün rəqəmlər, o cümlədən mənfi ədədlər üçün işləyir. Aşağı səviyyəli mərtəbələr də daxil olmaqla, sonsuz sayda mərtəbəsi olan bir göydələni təsəvvür edin (mənfi rəqəmləri təmsil edir). Əgər siz 2 ilə 3 arasında aşağı səviyyədə olan liftdəsinizsə (bu, -2,5 dəyəridir), Math.floor sizi -3-ə aparacaq:

Math.floor(-2.5); > -3
Ancaq bu cür vəziyyətdən qaçmaq istəyirsinizsə, bütün müasir brauzerlərdə dəstəklənən Math.trunc istifadə edin (IE/Edge istisna olmaqla):

Math.trunc(-41.43); > -41
MDN-də siz brauzerlərdə və IE/Edge-də Math.trunc üçün dəstək verəcək çoxlu doldurma tapa bilərsiniz.

Ən yaxın tam ədədə yuvarlaqlaşdırma

Digər tərəfdən, hər zaman yuvarlaqlaşdırmaq lazımdırsa, Math.ceil-dən istifadə edin. Yenə sonsuz lifti xatırlayırıq: Math.ceil rəqəmin mənfi olub-olmamasından asılı olmayaraq həmişə "yuxarı" qalxacaq:

Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36,93); > -36

Lazım olduqda yuxarı/aşağı yuvarlaqlaşdırın

Əgər biz 5-in ən yaxın qatına yuvarlaqlaşdırmaq istəyiriksə, ən asan yol ədədi 5-ə bölən, yuvarlaqlaşdıran və sonra eyni məbləğə vuran funksiya yaratmaqdır:

roundTo5(num) funksiyası ( Math.round(num/5)*5; qaytarın)
İndi:

RoundTo5(11); > 10
Dəyərinizin qatlarına yuvarlaqlaşdırmaq istəyirsinizsə, biz ilkin dəyəri və çoxluğu keçən daha ümumi funksiyadan istifadə edirik:

roundToMultiple(num, multiple) funksiyası ( Math.round(num/multiple)*multiple; ) qaytarın
İndi:

İlkin Nömrə = 11 olsun; çoxlu = 10; roundToMultiple(ilkin Nömrə, çoxlu); > 10;

Bir sıradakı nömrənin düzəldilməsi

Bir sıra daxilində olan x dəyərini əldə etmək istədiyimiz bir çox hal var. Məsələn, biz 1-dən 100-ə qədər bir dəyər istəyə bilərik, lakin biz 123 dəyəri ilə nəticələndik. Bunu düzəltmək üçün min (rəqəmlər dəstinin ən kiçiyini qaytarır) və max (hər hansı çoxluğun ən böyüyünü qaytarır) istifadə edə bilərik. rəqəmlərdən). Bizim nümunəmizdə diapazon 1-dən 100-ə qədərdir:

LowBound = 1 olsun; qoy highBound = 100; numInput = 123; let clamped = Math.max(lowBound, Math.min(numInput, highBound)); konsol jurnalı (sıxılmış); > 100;
Yenə də, Daniel X. Moore tərəfindən təklif olunan həll yolu istifadə edərək, əməliyyatdan yenidən istifadə edə və hamısını bir funksiyaya yığa bilərik:

Number.prototype.clamp = function(min, maks) ( return Math.min(Math.max(bu, min), max); );
İndi:

NumInput.clamp(lowBound, highBound); > 100;

Qauss yuvarlaqlaşdırma

Bankirin yuvarlaqlaşdırılması kimi də tanınan Qauss yuvarlaqlaşdırması, bu hal üçün yuvarlaqlaşdırmanın ən yaxın cüt ədədə olmasıdır. Bu yuvarlaqlaşdırma üsulu statistik xəta olmadan işləyir. Ən yaxşı həlli Tim Down təklif etdi:

Funksiya gaussRound(num, decimalPlaces) ( let d = decimalPlaces || 0, m = Math.pow(10, d), n = +(d ? num * m: num).toFixed(8), i = Math.floor (n), f = n - i, e = 1e-8, r = (f > 0,5 - e && f< 0.5 + e) ? ((i % 2 == 0) ? i: i + 1) : Math.round(n); return d ? r / m: r; }
İndi:

GaussRound(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
CSS-də ondalık nöqtə:

JavaScript tez-tez HTML elementləri üçün mövqe çevrilmələri yaratmaq üçün istifadə edildiyindən, elementlərimiz üçün onluq dəyərlər yaratsaq nə baş verdiyini maraqlandıra bilərsiniz:

#qutu (en: 63.667731993px; )
Yaxşı xəbər budur ki, müasir brauzerlər faiz və ya piksel vahidləri də daxil olmaqla qutu modelində onluq dəyərlərə hörmət edəcəklər.

Çeşidləmə

Çox tez-tez bəzi elementləri çeşidləməliyik, məsələn, bir sıra oyun qeydlərimiz var, halbuki onlar oyunçuların rütbəsinə görə azalan qaydada təşkil edilməlidir. Təəssüf ki, standart sort() metodunun bəzi təəccüblü məhdudiyyətləri var: o, ümumi ingilis sözləri ilə yaxşı işləyir, lakin rəqəmlər, unikal simvollar və ya böyük hərflərlə rastlaşdıqda dərhal sıradan çıxır.

Əlifba sırası ilə çeşidləyin

Belə görünür ki, massivi əlifba sırası ilə çeşidləmək ən sadə məsələ olmalıdır:

Qoy meyvə = ["butternut squash", "aricot", "qtaloupe"]; meyvə sort(); > "ərik", "kərəviz balqabağı", "qovun"]
Bununla belə, elementlərdən biri böyük hərflə yazılmış kimi problemlə qarşılaşırıq:

Qoy meyvə = ["butternut squash", "aricot", "Cantalope"]; meyvə sort(); > "Qovun", "ərik", "kərə yağı"]
Bunun səbəbi, standart olaraq, çeşidləyicinin Unicode-da təmsil olunan ilk simvolu müqayisə etməsidir. Unicode platformadan, proqramdan, dildən asılı olmayaraq istənilən simvol üçün unikal koddur. Məsələn, kod cədvəlinə baxarkən "a" simvolu U+0061 (onaltılıq 0x61), "C" simvolu isə Unicode simvolundan əvvəl gələn U+0043 (0x43) koduna malikdir. cədvəl. "a".

Qarışıq hərflərin ilk hərflərini ehtiva edə bilən massivi çeşidləmək üçün ya bütün elementləri müvəqqəti olaraq kiçik hərflərə çevirməli, ya da bəzi arqumentlərlə localeCompare() metodundan istifadə edərək öz çeşidləmə sıramızı təyin etməliyik. Bir qayda olaraq, belə bir vəziyyət üçün dərhal çoxlu istifadə üçün bir funksiya yaratmaq daha yaxşıdır:

AlphaSort(arr) ( arr.sort(funksiya (a, b) ( qaytarın a.localeCompare(b, "en", ("həssaslıq": "baza")); )); ) meyvə = ["butternut squash" edək "," ərik ", "Qontalup"]; alphaSort(meyvə) >
Əgər serialın əks əlifba sırası ilə çeşidlənməsini istəyirsinizsə, funksiyada a və b mövqelərini dəyişdirin:

Funksiya alphaSort(arr) ( arr.sort(funksiya (a, b) ( qaytarın b.localeCompare(a, "en", ("həssaslıq": "baza")); )); ) let fruit = ["butternut squash" "," ərik ", "Qontalup"]; alphaSort(meyvə) > ["Qarın", "kərə yağı", "ərik"]
Burada qeyd etmək lazımdır ki, localeCompare arqumentlərlə istifadə olunur, onun IE11+ tərəfindən dəstəkləndiyini də xatırlamaq lazımdır, IE-nin köhnə versiyaları üçün onu arqumentlərsiz və kiçik hərflərlə istifadə edə bilərik:

Funksiya caseSort(arr) ( arr.sort(funksiya (a, b) ( qaytarın a.toLowerCase().localeCompare(b.toLowerCase()); )); ) qoy meyvə = ["butternut squash", "aricot", "Qovun"]; caseSort(meyvə) > ["ərik", "kərə yağı", "qovun"]

Rəqəmsal çeşidləmə

Bütün bunlar yuxarıda oyun qeydləri silsiləsi haqqında danışdığımız nümunəyə aid deyil. Bəzi rəqəmli massivlərlə çeşidləmə çox yaxşı işləyir, lakin müəyyən nöqtədə nəticə gözlənilməz ola bilər:

HighScores = olsun; cür(); >
Fakt budur ki, sort() metodu leksikoqrafik müqayisəni həyata keçirir: bu o deməkdir ki, nömrələr sətirə çevriləcək və müqayisələr yenidən bu sətirin birinci simvolunu Unicode cədvəlinin simvollarının sırasına uyğunlaşdırmaqla aparılacaq. Buna görə də, yenidən çeşidləmə qaydamızı müəyyən etməliyik:

HighScores = olsun; highScores.sort(funksiya(a,b) ( a - b; ) qaytarın); >
Yenə də nömrələri tərs qaydada çeşidləmək üçün funksiyada a və b mövqelərini dəyişdirin.

JSON kimi strukturun çeşidlənməsi

Və nəhayət, bir sıra oyun qeydləri kimi təmsil olunan JSON kimi məlumat strukturumuz varsa:

Qoy xallar = [ ( "ad": "Daniel", "bal": 21768 ), ( "ad": "Maykl", "hesab": 33579 ), ( "ad": "Alison", "hesab": 38395 )];
ES6+-da siz ox funksiyalarından istifadə edə bilərsiniz:

Scores.sort((a, b) => b.score - a.score));
Bu dəstəyi olmayan köhnə brauzerlər üçün:

Scores.sort(funksiya(a, b) ( qaytarmaq a.bal - b.score ));
Gördüyünüz kimi, JavaScript-də çeşidləmə kifayət qədər aydın olmayan bir şeydir, ümid edirəm ki, bu nümunələr həyatı birtəhər asanlaşdırır.

Güc funksiyaları ilə işləmək

Eksponentasiya əvvəlcə natural ədədin özünə vurulması nəticəsində müəyyən edilən əməliyyatdır, a-nın kvadrat kökü kvadratı olduqda a verən ədəddir. Biz bu funksiyaları gündəlik həyatda riyaziyyat dərslərində, o cümlədən sahələri, həcmləri hesablayarkən və ya hətta fiziki modelləşdirmədə istifadə edə bilərik.

JavaScript-də eksponensial funksiya Math.pow() kimi təqdim olunur, yeni ES7 standartında yeni eksponentasiya operatoru təqdim edilmişdir - " * * ".

Ekponentasiya

Ədədi n-ci dərəcəyə qaldırmaq üçün Math.pow() funksiyasından istifadə edin, burada birinci arqument gücə qaldırılacaq ədəd, ikinci arqument isə eksponentdir:

Math.pow(3,2) > 9
Bu qeyd 3 kvadrat və ya 3 × 3 deməkdir, nəticədə 9 nəticə verir. Təbii ki, başqa bir misal da verilə bilər:

Math.pow(5,3); > 125
Yəni 5 kub və ya 5 × 5 × 5 125-ə bərabərdir.

ECMAScript 7 JavaScript-in növbəti versiyasıdır, prinsipcə biz təklif olunan yeni eksponentasiya operatorundan istifadə edə bilərik - * *, bu yazı forması daha təsviri ola bilər:

3 ** 2 > 9
Hazırda bu operatora dəstək kifayət qədər məhduddur, ona görə də ondan istifadə etmək tövsiyə edilmir.

Güc funksiyası müxtəlif vəziyyətlərdə faydalı ola bilər. Sadə bir misal, bir saatda saniyələrin sayının hesablanması: Math.pow(60,2).

Kvadrat və kub kök

Math.sqrt() və Math.cbrt() Math.pow() funksiyasının əksidir. Xatırladığımız kimi, a-nın kvadrat kökü, kvadrat olduqda a verən ədəddir.

Math.sqrt(9) > 3
Eyni zamanda, a-nın kub kökü kub olduqda a verən ədəddir.

Math.cbrt(125) > 5
Math.cbrt() JavaScript spesifikasiyasına çox yaxınlarda təqdim edildi və buna görə də yalnız müasir brauzerlərdə dəstəklənir: Chrome 38+, Firefox və Opera 25+ və Safari 7.1+. Internet Explorer-in bu siyahıda olmadığını görəcəksiniz, lakin MDN-də çoxlu doldurma tapa bilərsiniz.

Nümunələr

Əlbəttə ki, bu funksiyalardan birində tam olmayan dəyərlərdən də istifadə edə bilərik:

Math.pow(1.25, 2); > 1.5625 Math.cbrt(56.57) > 3.8387991760286138
Qeyd edək ki, bu, mənfi arqument dəyərlərindən istifadə edərkən də işləyir:

Math.pow(-5,2) > 25 Math.pow(10,-2) > 0.01
Lakin, kvadrat kök üçün bu işləməyəcək:

Math.sqrt(-9) > NaN
Riyazi analizdən bilirik ki, xəyali ədəd mənfi ədədlərin kvadrat kökləri kimi başa düşülür. Və bu bizi başqa bir mürəkkəb nömrə texnikasına apara bilər, amma bu başqa hekayədir.

Siz ədədlərin kvadrat və kub köklərini tapmaq üçün Math.pow() proqramında kəsr dəyərlərindən istifadə edə bilərsiniz. Kvadrat kök 0,5 eksponentindən istifadə edir:

Math.pow(5, 0,5); // = Math.sqrt(5) = 5 ** (1/2) > 2,23606797749979
Bununla belə, üzən nöqtənin şıltaqlığına görə düzgün nəticəni dəqiq təxmin edə bilməzsiniz:

Math.pow(2.23606797749979.2) > 5.000000000000001
Belə vəziyyətlərdə nömrələrdən işarələri kəsməyə və ya müəyyən bir dəyərə yuvarlaqlaşdırmağa müraciət etməli olacaqsınız.

Bəziləri JavaScript-də izah oluna bilməyəcək şəkildə Math.pow() funksiyasını Math.exp() ilə qarışdırırlar ki, bu da ümumilikdə ədədlər üçün eksponensial funksiyadır. Qeyd: İngilis dilində "exponent" "eksponent" kimi tərcümə olunur, buna görə də bu, ingilis dilində danışanlara daha uyğundur, baxmayaraq ki, göstərici üçün indeks, güc kimi alternativ adlar var.

Riyazi sabitlər

JavaScript-də riyaziyyatla işləmək bir sıra daxili sabitlər sayəsində asanlaşdırılır. Bu sabitlər Math obyektinin xassələridir. Qeyd etmək lazımdır ki, sabitlər CamelCase notasiyası ilə deyil, böyük hərflə yazılır.

Sorğuda yalnız qeydiyyatdan keçmiş istifadəçilər iştirak edə bilər. , Zəhmət olmasa.

Teqlər: Teqlər əlavə edin

Xatırladıram ki, bu yeni başlayanlar üçün giriş JavaScript kursu. Bu gün nəyə baxacağıq operatorlar mövcüd olmaq JavaScript-də. Təhlükəsizlik kəmərlərini bağlayın! Bukaf çox olacaq.

Bir dəstə məlumatınız olduqda, onunla bir şey etməlisiniz. Operatorlar sadəcə bizneslə məşğuldurlar. Həmişə toplayırlar, vururlar, bölürlər, çıxarırlar, müqayisə edirlər, mənimsəyirlər və nə edirlər. Proqramlaşdırmada operatorlar olmadan sadəcə sıyıq bişirmək olmaz.

JavaScript aşağıdakı operator növlərini istifadə edir:

  • Arifmetik operatorlar
  • Təyinat operatorları
  • Müqayisə operatorları
  • Məntiqi operatorlar
  • Simli operatorlar
  • Şərti ifadələr

Bu tam siyahı deyil, lakin yeni başlayanlar üçün bu, gözlər üçün kifayətdir. Təqdim olunan hər bir operator növünü, nə üçün lazım olduğunu və nə ilə yeyildiyini təhlil edəcəyik. Get!

JavaScript-də Arifmetik Operatorlar

Siz məktəbdən arifmetik operatorlarla tanışsınız. Bunlar toplama, çıxma, bölmə və vurmanın adi əlamətləridir: + , - , / , * . Müvafiq olaraq, onlar adi riyaziyyatda olduğu kimi proqramlaşdırmada da eyni funksiyaları yerinə yetirirlər. Bununla bağlı heç bir çətinlik çəkməyəcəksiniz.

Operatorların işlədiyi verilənlər adlanır operandlar.

2 + 3 // burada 2 və 3 nömrələri operandlar, + işarəsi isə toplama operatorudur.

Riyaziyyatda olduğu kimi, arifmetik operatorların da öz üstünlüyü var: vurma və bölmənin toplama və çıxma işlərindən daha yüksək üstünlüyü var.

2 + 3 * 4 // burada əvvəlcə vurma, sonra isə toplama yerinə yetirilir

Riyaziyyatda olduğu kimi, mötərizələr də üstünlüyü dəyişdirmək üçün fəal şəkildə istifadə olunur:

(2 + 3) * 4 // əvvəlcə buraya əlavə edin, sonra çoxaldın

Yeri gəlmişkən, = işarəsi də operatordur. Haqqında məqalədə artıq öyrəndiyimiz kimi, bu, təyinat operatorudur və ümumiyyətlə bərabərlik işarəsi deyil. Bu barədə unutmayın!

Modul operatoru

İndi daha maraqlı arifmetik operatorlara baxaq. Faiz işarəsi isə birinci olacaq - % . JavaScript-də bu, ümumiyyətlə sözün faizi deyil. Beləliklə, proqramlaşdırmada modul bölgüsü göstərilir. Belə bir əməliyyatın nəticəsi bölmənin qalan hissəsi olacaqdır. Misal üçün:

100% 22 // qalıq 12 olacaq
100% 10 // qalıq 0 olacaq

Hesablamalarda bu operator bölmə ilə vurma ilə eyni üstünlüyə malikdir, ona görə də mötərizələrdən istifadə etməyi unutmayın.

Operator birləşməsi

= operatoru qeydi qısaltmaq üçün digər operatorlarla birləşdirilə bilər və birləşdirilməlidir. Misal:

varn = 2; // dəyişənə n dəyərini təyin edin 2
n = n + 3; // n dəyişəninə yeni n + 2 qiymətini təyin edirik, 5 alırıq

Eyni şeyi belə yazmaq olar:

varn = 2;
n += 3; // n = n + 3 yazısına bərabərdir

Artırma ++ və azalma operatorları – –

Arifmetik operatorlar arasında bir neçə çox maraqlı olanlar var - artımazalma. Onlar müvafiq olaraq ++ və –– ilə işarələnirlər. Birinci dəyişəni bir artırır, ikincisi isə onu azaldır. Bu xüsusiyyət proqramlaşdırmada çox istifadə olunur, çünki çox rahatlıq təmin edir. Çox vaxt şərti ifadələrdə tapıla bilər, lakin bu barədə daha sonra.

Hər iki operatorun qeyddə xüsusi yeri var. İçindəki kimi ola bilərlər prefiks forma (dəyişəndən əvvəl) ++n , və in postfiks(dəyişəndən sonra) n++ . Fərq böyükdür! Bu formaları heç vaxt qarışdırmayın və onları yaxşı əzbərləyin. Əgər bu operatorlar dəyişənin qarşısında görünürsə, nəticədə onun qiyməti 1 artır. Amma! Əgər onlar dəyişəndən sonra gəlirsə, o zaman orijinal dəyəri qaytarırlar. Misal:

var n = 2, m = 0;
m = ++n // n-i 1 (n = 3) artırın və m-ni də 3-ə təyin edin

var n = 2, m = 3;
m = n++ // n-i 1-ə artırır (n = 3), lakin m-ni əvvəlki qiymətə təyin edir n = 2

Birinci nümunə ilə əminəm ki, siz bunu asanlıqla başa düşə bilərsiniz. Ancaq ikincisi problemli ola bilər. Bu şeyi başa düşməyi asanlaşdırmaq və çaşqınlıq yaratmamaq üçün təsəvvür edin ki, siz əvvəlcə m dəyişəninin qiymətini n dəyişəninə təyin etdiniz və bundan sonra n-in qiymətini bir artırdınız. Birinci misalda siz əvvəlcə n dəyərini bir artırdınız, sonra isə bu dəyəri m dəyişəninə təyin etdiniz.

Arifmetik operatorlarla belədir. Əlbəttə ki, bu sadə operatorların istifadəsində hələ də bir çox varyasyonlar və incəliklər var, lakin bu işə başlamaq üçün kifayət qədər çox olacaq.

Müqayisə operatorları

Yenidən riyaziyyata qayıdaq. İşarələr hər kəsə və hər kəsə tanışdır. Proqramlaşdırmada onlara deyilir müqayisə operatorları. JavaScript aşağıdakı müqayisə operatorlarından istifadə edir:

< меньше
> daha çox
<= меньше или равно
>= böyük və ya bərabərdir
== bərabərdir
!= bərabər deyil
=== ciddi bərabərdir
!== qəti şəkildə bərabər deyil

Qeyd edək ki, "böyük və ya bərabər" işarəsi => deyil, >= kimi yazılır. Yəni ox bərabərlik işarəsindən əvvəldir, ondan sonra deyil.

Müqayisə operatorları dəyişənlərin dəyərlərini müqayisə etməyə imkan verir və bu əməliyyatın nəticəsi həmişə doğru və ya yanlış bir boolean dəyərdir. Onlar adətən şərti ifadələrdə istifadə olunur. Müqayisə nəticəsində kodun hansı hissəsinin növbəti icra olunacağını müəyyənləşdirir.

JavaScript-də siz eyni zamanda müxtəlif məlumat növlərini müqayisə edə bilərsiniz, məsələn, nömrə və sətir:

12345 == "12345" // doğrudur

Məhz bu halda sətir avtomatik olaraq nömrəyə çevrilir. Ciddi bərabərlik === və ya bərabərsizlik!== yalnız eyni tipli dəyişənlərin müqayisəsi zamanı istifadə olunur.

Məntiqi operatorlar

JavaScript-də Boolean əməliyyatları yeni başlayanlar üçün olduqca çətin mövzulardan biridir. Dili mənimsəməkdə uğurla irəliləmək üçün onu yaxşı başa düşməyə dəyər. Onlar ən çox müqayisə operatorları ilə birlikdə istifadə olunur və doğru və ya yalanın boolean dəyərini yaradır.

Üç məntiqi operator var:

&& (VƏ)
|| (OR)
! (YOX)

Boolean operatoru && (AND)

&& operatoru iki qiymət üzərində məntiqi AND əməliyyatını yerinə yetirir. Bununla belə, yalnız və yalnız hər iki operand doğru olduqda doğru qaytarır. Operandlardan biri və ya hər ikisi false kimi qiymətləndirilərsə, operator false qaytarır. Nümunələr:

2 < 3 && 4 < 5 // true
2 < 3 && 5 < 4 // false
3 < 2 && 5 < 4 // false

Məntiqi operatorlar müqayisə operatorlarına nisbətən daha az üstünlüyə malikdirlər, ona görə də verilən nümunələrdə mötərizəsiz edirik. Aydındır ki, əvvəlcə rəqəmləri bir-birimizlə müqayisə edirik və yalnız bundan sonra məntiqi tətbiq edirik.

Məntiqi operator || (OR)

|| məntiqi operatoru ilə (YA) başqa mahnı. Operator || iki operand üzərində məntiqi OR əməliyyatını yerinə yetirir. Əgər operandlardan biri və ya hər ikisi doğrudursa, o, doğrunu qaytarır. Hər iki operand yalan olarsa, yalan qaytarır. Nümunələr:

2 < 3 || 4 < 5 // true
2 < 3 || 5 < 4 // true
3 < 2 || 5 < 4 // false

Məntiqi operatorların bir hiyləsi var. Əlavə işi sevmirlər. Bununla belə, və mən. Onlar həmişə öz hesablamalarına soldan sağa başlayırlar. Əgər ifadənin birinci hissəsi onların şərtlərinə uyğun gəlirsə, o zaman ifadənin qalan hissəsini belə qiymətləndirmirlər.

Məsələn, əgər operator || ən başlanğıcda həqiqi dəyəri tapır, sonra dərhal həqiqi dəyəri verir, qalanları isə artıq yoxlanılmır. Həm də && operatoru, əgər lap əvvəlində yanlış ifadə tapsa, dərhal yanlış nəticə verir, qalanını yoxlayır.

Və daha bir şey: AND && operatorunun prioriteti OR || operatorundan daha böyükdür , buna görə də əvvəl icra edir:

2 < 3 || 4 < 5 && 5 < 6 // здесь сначала будет выполнено вычисление в правой части, а потом уже в левой

Məntiq operatoru! (YOX)

Məntiq operatoru! "məntiqi DEYİL" deməkdir. Yalnız bir operandla istifadə olunur və həmin operandın dəyərini tərsinə çevirir. Əgər n doğrudursa, onda !n yalan olacaq. Bu operator yalnız bir operanda əlavə oluna bildiyi üçün bütün ifadəni tərsinə çevirmək üçün o, mötərizədə alınmalıdır!(n && m) .

Simli operatorlar

Biz əvvəllər simli operatorlar haqqında danışdıq. Bu, simli dəyişənləri birləşdirmək üçün istifadə olunan eyni + və ya başqa şəkildə - üçün birləşmə(sətir əlavə). Misal:

"İqor" + "Kventor" == "İqor Kventor"

Diqqət yetirin ki, ilk sözdə bağlanış dırnaq işarəsindən əvvəl boşluq əlavə olunur. Əlavə edilmədikdə, sətirlər bir sözlə birləşəcək "IgorQuentor" .

Bu operatorun bir xüsusiyyəti var: ifadədə ən azı bir sətir varsa, o və bütün digər arqumentlər sətir tipinə gətirib çıxarır. Misal üçün:

Qalan arifmetik operatorlar yalnız ədədlərlə işləyir və həmişə öz arqumentlərini ədədə verirlər.

Şərti ifadələr

JavaScript-in iki şərti ifadəsi var if və ?: Baxmayaraq ki, daha dəqiq desək, if əslində nəzarət ifadəsidir və kifayət qədər genişdir, çoxlu yaxşılıqlar və maraqlı xüsusiyyətlərdir. Buna görə də bu barədə ayrıca məqalə olacaq. Hələlik daha sadə şərti operatora baxaq?:

Adətən bu operator ? kimi yazılır: Amma proqramlarda fərqli görünür. Onun üç operandı var. Birinci operand simvoldan əvvəldirmi? , ikincisi simvollar arasındadır? və: üçüncü - sonra:

vəziyyət? dəyər 1: dəyər 2

Onun işinin mənası sadədir: müəyyən edilmiş şərt yerinə yetirilərsə, 1 dəyəri qaytarılır, yoxsa, dəyəri 2. Bu şərti operator çox vaxt if ifadəsinin daha sadə əvəzedicisi kimi xidmət edir, əgər sonuncu xüsusilə zəruri deyildir. Eyni zamanda, qeydin özü qısaldılır və oxunması asanlaşdırılır.

Hələlik, hamısı budur!

Ümid edirəm ki, indi JavaScript-də operatorlar haqqında bir az anlayışınız var. Beyin qaynamasın deyə, qısaca cizgi filmi sizə rahatlıq verir - Proqramçı hər şeyi edə bilər! :)

Əgər siz JavaScript-də yenisinizsə, "modle bundlers vs. module loaders", "Webpack vs. Browserify" və "AMD vs. CommonJS" kimi jarqonlar sizi çaşdıra bilər.

JavaScript-dəki modul sistemi qorxuducu ola bilər, lakin onu anlamaq tərtibatçılar üçün çox vacibdir.

Bu yazıda hər şeyi sadə dillə izah etməyə çalışacağam (bir neçə kod nümunəsi ilə). Ümid edirəm ki, bu məqalə sizin üçün faydalıdır.

Qeyd: Rahatlıq üçün məqalə iki hissəyə bölünəcəkdir. Birinci hissədə modulların nə olduğunu və onlardan nə üçün istifadə etdiyimizi nəzərdən keçirəcəyik. İkinci hissədə modulları vahid bütövlükdə birləşdirməyin müxtəlif yollarına baxacağıq.

Kimsə modulların nə olduğunu yenidən izah edə bilərmi?

Kitabdakı fəsillər kimi, modullar sadəcə sözlərdən ibarət qruplardır (və ya vəziyyətə uyğun olaraq kod).

Yaxşı modulların öz funksiyaları var, belə ki, bütün sistemi pozmadan lazım olduqda əlavə etmək, köçürmək və ya çıxarmaq olar.

Niyə ümumiyyətlə modullardan istifadə olunur?

Əslində modulların bir çox üstünlükləri var. Ən vacibləri, mənim fikrimcə, aşağıdakılardır:

  1. Rahat dəstək (saxlanılabilirlik): Tərifə görə, modul öz-özünə əhatə olunur. Yaxşı dizayn edilmiş modul kod bazanızın hissələrinin asılılığını mümkün qədər azaltmaq üçün nəzərdə tutulmuşdur ki, o, bir-birindən asılı olmayaraq inkişaf edə və təkmilləşə bilsin. Kodun digər hissələrindən ayrı olduqda bir modulu yeniləmək daha asandır. Kitabımıza qayıdaraq, məsələn, bir fəsildə kiçik bir dəyişiklik etmək istəyirsinizsə və bu, kitabınızın bəzi digər hissəsini dəyişdirirsə, o, kabus olmaq. Ona görə də fəsli elə yazmaq lazımdır ki, redaktə edərkən başqa fəsillərə təsir etmək lazım olmasın.
  2. Ad boşluqları (Ad boşluğu): JavaScript-də yüksək səviyyəli funksiyalardan kənar olan dəyişənlər qlobal hesab olunur (hər kəs onlara daxil ola bilər). Buna görə də, tamamilə əlaqəsiz kodun qlobal dəyişənlərlə bağlandığı "ad sahəsinin çirklənməsi" çox yaygındır. Qlobal dəyişənlərin əlaqəli olmayan kodda paylaşılması inkişafda çox pisdir. Bu məqalənin sonrasında modulların bizə məlumatları çirkləndirməmək üçün imkan verdiyini görəcəyik. dəyişənlərimiz üçün şəxsi boşluqlar yaratmaqla qlobal ad sahəsi.
  3. Yenidən istifadə oluna bilər: Gəlin səmimi olaq. Hamımız əvvəllər yazdığımız yeni layihələrə kodu kopyaladıq. Məsələn, təsəvvür edək ki, siz əvvəlki layihədən bəzi köməkçi metodları yeni layihəyə köçürmüsünüz.Yaxşı, lakin bu hissəni yazmağın ən yaxşı yolunu tapsanız, yeniləmək üçün bu kodun göründüyü bütün yerləri yadda saxlamalı olacaqsınız. Bu, şübhəsiz ki, böyük vaxt itkisidir. Modul yazmaq və onu təkrar-təkrar istifadə etmək çox asan olardı.

Modulları necə inteqrasiya etmək olar?

Modulları proqramlarınıza inteqrasiya etməyin bir çox yolu var. Onlardan bəzilərinə nəzər salaq:

Nümunə "Modul"

Modul nümunəsi siniflər konsepsiyasını təqlid etmək üçün istifadə olunur (çünki JavaScript sinifləri dəstəkləmirdi), buna görə də biz ictimai və şəxsi metodları (dəyişənləri) eyni obyektdə saxlaya bilərik, Java və ya digər dillərdəki siniflər kimi. Python edir. Bu, bizə ictimai API yaratmağa və özəl dəyişənlər və metodlar bağlanarkən ictimai metodlara daxil olmaq imkanı verir.

Modul modelini həyata keçirməyin bir neçə yolu var. Birinci misalda anonim bağlamalardan istifadə edəcəyəm. Kodu anonim funksiyaya yerləşdirmək bizə məqsədimizə çatmağa kömək edəcək. (Unutmayın ki, JavaScript-də funksiyalar yeni əhatə dairəsi yaratmağın yeganə yoludur.)

Misal 1: Anonim bağlanmalar

(funksiya () ( // Biz bu dəyişənləri bu bağlama daxilində gizli saxlayırıq var myGrades = ; var orta = function() ( var total = myGrades. reduce(function(accumulator, item) ( qaytarılması akkumulyator + element), 0); return "Orta qiymətiniz " + cəmi / myGrades.length + "."; ) var failing = function()( var failingGrades = myGrades.filter(function(item) ( elementi qaytarın)< 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); }());

Beləliklə, anonim funksiyamızın öz əhatə dairəsi və ya "bağlanması" var və biz onu dərhal icra edə bilərik. Bu üsul bizə dəyişənləri əsas (qlobal) əhatə dairəsindən gizlətməyə imkan verir.

Bu yanaşmanın həqiqətən gözəl tərəfi odur ki, siz bu funksiyanın daxilində yerli dəyişənlərdən istifadə edə bilərsiniz və təsadüfən eyni adlı qlobal dəyişənlərin üzərinə yazmaqdan qorxmursunuz. Ancaq yenə də qlobal dəyişənlərə girişiniz var, məsələn:

Var global = "Salam, mən qlobal dəyişənəm :)"; (funksiya () ( // Biz bu dəyişənləri bu bağlama daxilində gizli saxlayırıq var myGrades = ; var orta = function() ( var total = myGrades. reduce(function(accumulator, item) ( qaytarılması akkumulyator + element), 0); return "Orta qiymətiniz " + cəmi / myGrades.length + "."; ) var failing = function()( var failingGrades = myGrades.filter(function(item) ( elementi qaytarın)< 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); console.log(global); }()); // "You failed 2 times." // "Hello, I am a global variable:)"

Misal 2: Qlobal İdxal

JQuery kimi kitabxanaların istifadə etdiyi digər məşhur yanaşma qlobal idxaldır. Bu, indi gördüyümüz qapanmalara bənzəyir, yalnız indi qlobal dəyişənləri parametrlər kimi ötürürük.

(funksiya (globalVariable) ( // Bu dəyişənləri bu bağlama daxilində gizli saxlayın var privateFunction = function() ( console.log("Şşşşş, bu özəldir!"); ) // GlobalVariable interfeysi vasitəsilə aşağıdakı üsulları ifşa edərkən / / // function() bloku daxilində metodun həyata keçirilməsini gizlətmək globalVariable.each = function(toplama, iterator) ( if (Array.isArray(collection)) ( üçün (var i = 0; i)< collection.length; i++) { iterator(collection[i], i, collection); } } else { for (var key in collection) { iterator(collection, key, collection); } } }; globalVariable.filter = function(collection, test) { var filtered = ; globalVariable.each(collection, function(item) { if (test(item)) { filtered.push(item); } }); return filtered; }; globalVariable.map = function(collection, iterator) { var mapped = ; globalUtils.each(collection, function(value, key, collection) { mapped.push(iterator(value)); }); return mapped; }; globalVariable.reduce = function(collection, iterator, accumulator) { var startingValueMissing = accumulator === undefined; globalVariable.each(collection, function(item) { if(startingValueMissing) { accumulator = item; startingValueMissing = false; } else { accumulator = iterator(accumulator, item); } }); return accumulator; }; }(globalVariable));

Bu nümunədə GlobalVariable yeganə qlobal dəyişəndir. Bu yanaşmanın üstünlüyü ondan ibarətdir ki, siz bütün qlobal dəyişənləri əvvəlcədən elan edirsiniz ki, bu da kodunuzu başqaları üçün şəffaf edir.

Misal 3: Obyekt interfeysi

Modullar yaratarkən başqa bir yanaşma, müstəqil, obyekt əsaslı interfeyslərdən istifadə etməkdir, məsələn:

Var myGradesCalculate = (funksiya () ( // Bu dəyişəni bu bağlama daxilində gizli saxlayın var myGrades = ; // Gizləyərkən bu funksiyaları interfeys vasitəsilə ifşa edin // modulun function() blokunda həyata keçirilməsi qaytarılması (orta: funksiya) () ( var total = myGrades.reduce(funksiya(akkumulyator, element) ( qaytarılması akkumulyator + maddə; ), 0); return"Orta qiymətiniz " + cəmi / myGrades.length + "."; ), uğursuz: funksiya () ( var failingGrades = myGrades.filter(funksiya(item) ( elementi qaytarın< 70; }); return "You failed " + failingGrades.length + " times."; } } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

Gördüyünüz kimi, bu yanaşma bizə hansı dəyişənləri (metodları) özəl etmək istədiyimizə qərar verməyə imkan verir (məsələn, mənimGrades ) və hansıları qaytarılmış obyektə yerləşdirməklə ictimaidir (məsələn, orta uğursuz ).

Nümunə 4: Popup Modul Modeli

Bu nümunə əvvəlkinə çox bənzəyir, istisna olmaqla, bütün metodlar və dəyişənlər açıq şəkildə ifşa olunana qədər özəl qalır.

Var myGradesCalculate = (funksiya () ( // Bu dəyişəni bu bağlama daxilində gizli saxlayın var myGrades = ; var orta = function() ( var total = myGrades. azaltma(funksiya(akkumulyator, maddə) ( akkumulyator + maddə; ), 0); return"Orta qiymətiniz " + cəmi / myGrades.length + "."; ); var failing = function() ( var failingGrades = myGrades.filter(function(item)) ( elementi qaytarın)< 70; }); return "You failed " + failingGrades.length + " times."; }; // Explicitly reveal public pointers to the private functions // that we want to reveal publicly return { average: average, failing: failing } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

Bu, çoxlu məlumat kimi görünə bilər, lakin modul nümunələrinə gəldikdə bu, aysberqin yalnız görünən hissəsidir. Araşdırma apararkən tapdığım bəzi faydalı mənbələr bunlardır:

  • Addy Osmani tərəfindən: bu, təfərrüatların xəzinəsidir və qəti şəkildə qısa məzmundur;
  • Adequately Good by Ben Cherry : "Modul" nümunəsinin qabaqcıl istifadəsi nümunələri ilə faydalı icmal;
  • Carl Danley bloqu: Modul nümunəsi və digər JavaScript nümunələri üçün resursların icmalı;

CommonJS və AMD

Yuxarıda sadalanan bütün yanaşmaların ümumi bir cəhəti var: onların hamısı funksiya kodunun yerləşdiyi bir qlobal dəyişən yaradır və bununla da şəxsi ad məkanı yaradır və bağlanmanın əhatə dairəsindən istifadə edir.

Bu yanaşmaların hər biri özünəməxsus şəkildə təsirli olsa da, onların çatışmazlıqları da var.

Bir tərtibatçı olaraq düzgün fayl yükləmə sırasını bilməlisiniz. Məsələn, deyək ki, siz layihənizdə Backbone istifadə edirsiniz, ona görə də siz faylınızdakı teq vasitəsilə Backbone skriptini daxil edirsiniz. Backbone birbaşa Underscore.js-dən asılı olduğundan, siz Backbone.js skriptini Underscore.js-dən əvvəl daxil edə bilməzsiniz.

Bir tərtibatçı üçün asılılıqları idarə etmək bəzən başağrısı olur.

Başqa bir çatışmazlıq, ad məkanı münaqişələrinin hələ də baş verə bilməsidir. Məsələn, eyni adlı iki modulunuz və ya eyni modulun iki versiyası ola bilər və hər ikisinə ehtiyacınız var.

Buna əsaslanaraq maraqlı sual yaranır: modul interfeysinə qlobal miqyasda deyil, daxil ola bilərikmi?

Xoşbəxtlikdən, cavab bəli.

İki məşhur və yaxşı tətbiq olunan yanaşma var: CommonJS və AMD.

Ümumi JS

CommonJS modulların elan edilməsi üçün JavaScript API dizayn və həyata keçirən könüllü inkişaf qrupudur.

CommonJS modulu təkrar istifadə üçün nəzərdə tutulmuş JavaScript kodunun bir parçasıdır. O, xüsusi obyektləri ixrac edərək, onları digər modullar üçün əlçatan edir ki, onları öz asılılıqlarına daxil etsinlər. Əgər siz Node.js-də proqramlaşdırmısınızsa, bu sizə çox tanış olacaq.

CommonJS ilə hər bir JavaScript faylı modulu özünəməxsus kontekstdə saxlayır (eynilə bağlanmalar kimi). Bu məkanda obyektdən istifadə edirik modul.exports modulları ixrac etmək və tələb edir onları birləşdirmək üçün.

CommonJS modulunun tərifi belə görünə bilər:

myModule() funksiyası ( this.hello = function() ( "salam!" qaytarın; ) this.goodbye = function() ( "əlvida!" qaytarın; ) ) module.exports = myModule;

Xüsusi bir obyektdən istifadə edirik modul və funksiyamıza bir keçid yerləşdirin modul.exports . CommonJS modulu başqa faylların istifadə edə bilməsi üçün açmaq istədiyimizi belə bilir.

Bundan sonra kimsə istifadə etmək istəyəndə bizim myModule, onu asanlıqla aşağıdakı kimi birləşdirə bilər:

Var myModule = tələb ("myModule"); var myModuleInstance = new myModule(); myModuleInstance.hello(); // "Salam!" myModuleInstance.goodbye(); // "əlvida!"

Bu yanaşmanın əvvəllər müzakirə etdiyimiz yanaşmalardan iki aydın üstünlüyü var:

  1. Qlobal ad məkanının çirklənməsinin olmaması;
  2. Asılılığımızı daha aydın etmək;

Həmçinin, çox yığcam sintaksis, mən onu çox sevirəm.

Qeyd etmək lazımdır ki, CommonJS istifadə edir əvvəlcə server yanaşma və modullar sinxron şəkildə yüklənir. Bu vacibdir, çünki birləşdirmək lazım olan daha üç modulumuz varsa, onları bir-bir yükləyəcək.

Hal-hazırda bu, serverdə yaxşı işləyir, lakin təəssüf ki, brauzer əsaslı JavaScript yazmağı çətinləşdirir. İnternetdən modul əldə etmək, modulu sabit diskdən əldə etməkdən daha uzun çəkir. Skript modulu yükləyərkən, brauzer bloklanır və yükləməni bitirənə qədər heç nə edə bilməzsiniz. O, belə davranır, çünki kod yüklənərkən JavaScript axını dayanır (modulların qurulmasına baxdığımız zaman məqalənin ikinci hissəsində bu problemi necə həll edə biləcəyimizi sizə deyəcəyəm. . Hələlik bilmək lazım olan tək şey budur.)

AMD

CommonJS əladır, amma modulları asinxron yükləməli olsaq necə olar? Bu sualın cavabı "Asinxron Modul Tərifi" və ya sadəcə AMD-dir.

Define(["myModule", "myOtherModule"], function(myModule, myOtherModule) ( console.log(myModule.hello()); ));

Modul tərifi funksiyası ilk arqument kimi bir sıra asılılıqları götürür. Bu asılılıqlar arxa planda (bloklanmayan) yüklənir və ikinci arqument kimi ötürülən geri çağırış funksiyasını çağırır.

Sonra geri çağırış funksiyası artıq yüklənmiş asılılıqları arqument kimi qəbul edir və onlardan istifadə etməyə imkan verir. Nəhayət, asılılıqların özləri də açar sözdən istifadə etməklə müəyyən edilməlidir müəyyənləşdirmək .

Misal üçün, myModule belə görünə bilər:

Define(, function() ( return ( salam: function() ( console.log("salam"); ​​), əlvida: function() ( console.log("əlvida"); ) ); ));

Beləliklə, bir daha keçək. CommonJS-dən fərqli olaraq, AMD asinxron davranışla yanaşı brauzerin ilk yanaşmasını tətbiq edir (Qeyd edək ki, bir çox insanlar kodunuzu icra edərkən dinamik fayl yükləməsinin əlverişli olmadığını iddia edirlər. Bu barədə modulların qurulması ilə bağlı məqaləmizin növbəti hissəsində daha ətraflı danışacağıq. ).

AMD-nin asinxron olması ilə yanaşı daha bir üstünlüyü var. AMD modulları funksiyalar, konstruktorlar, sətirlər, JSON və digər növlər ola bilər, CommonJS isə yalnız modul kimi obyektləri dəstəkləyir.

Mənfi tərəfi, AMD io, fayl sistemi və CommonJS vasitəsilə mövcud olan digər serverə xas xüsusiyyətlərlə uyğun gəlmir. Modul bəyanetmə funksiyasının sintaksisi sadə ilə müqayisədə ətraflıdır tələb edir .

UMD

Həm AMD, həm də CommonJS funksiyaları üçün dəstək tələb edən layihələr üçün başqa bir format var. Universal Modul Tərifi və ya sadə UMD.

Əslində, UMD yuxarıda göstərilən iki üsuldan hər hansı birini istifadə etmək imkanı verir, üstəlik qlobal dəyişən vasitəsilə modulların müəyyənləşdirilməsini dəstəkləyir. Nəticədə, UMD modulları həm müştəridə, həm də serverdə işləyə bilər.

UMD-nin necə işlədiyinə dair qısa bir nümunə:

(funksiya (kök, zavod) ( if (növü müəyyən === "funksiya" && müəyyən.amd) ( // AMD müəyyən (["myModule", "myOtherModule"], zavod); ) else if (ixrac növü == = "obyekt") ( // CommonJS module.exports = zavod(tələb("myModule"), tələb("myOtherModule")); ) else ( // Brauzer qlobalları (Qeyd: kök pəncərədir) root.returnExports = zavod( root.myModule, root.myOtherModule); ) )(bu, funksiya (myModule, myOtherModule) ( // Metodlar funksiyası notHelloOrGoodbye()(); // Şəxsi metod funksiyası hello()(); // İctimai metod, çünki o "s returned (aşağıya bax) funksiyası goodbye()(); // Açıq üsul, çünki o, qaytarılıb (aşağıya bax) // Açıq açıq metodlar qaytarılır ( salam: salam, əlvida: əlvida ) )));

Yerli JS

Fuuuh. Sən hələ də yanındasan? Mən səni bu meşədə itirmədim? Yaxşı! Çünki bizdə modul tərifinin başqa bir növü var.

Yuxarıda gördüyünüz kimi, modulların heç biri JavaScript üçün doğma deyildi. Bunun əvəzinə, ya Modul nümunəsi, CommonJS və ya AMD istifadə edərək modul sistemini simulyasiya etdik.

Xoşbəxtlikdən, TC39-da (ECMAScript-in sintaksisini və semantikasını təyin edən standart orqan) ağıllı insanlar ECMAScript 6 (ES6)-a daxili qurğular əlavə etdilər.

ES6 modulların idxalı və ixracı üçün müxtəlif variantları təklif edir, bu barədə bir dəfədən çox danışılmışdır. Budur bir neçə resurs:

  • jsmodules.io
  • exploringjs.com

ES6 modulları haqqında CommonJS və AMD ilə müqayisədə nə yaxşıdır? Hər iki dünyanın ən yaxşısını bir araya gətirir: yığcamlıq, deklarativ sintaksis, asinxron yükləmə, üstəgəl dairəvi asılılıqlar kimi əlavə üstünlüklər.

Yəqin ki, ES6 modullarının mənim sevimli xüsusiyyətim idxalın yalnız oxuna bilən ixrac növləri olmasıdır (idxalın yalnız ixracın surəti olduğu CommonJS ilə müqayisədə).

Bunun necə işlədiyinə dair bir nümunə:

// lib/counter.js var counter = 1; funksiya artım() ( sayğac++; ) funksiya azalma() ( əks--; ) modul.exports = ( sayğac: sayğac, artım: artım, azalma: azalma ); // src/main.js var counter = tələb edir("../../lib/counter"); counter.increment(); console.log(counter.counter); // 1

Bu nümunədə biz baza modulunun iki nüsxəsini çıxardıq: ilk dəfə ixrac etdikdə, ikinci dəfə idxal etdikdə.

Bundan əlavə, içərisində olan nüsxə main.js indi orijinal moduldan ayrılıb. Belə ki, sayğacımızı artırsaq belə, yenə də 1-i qaytarır, çünki sayğac moduldan idxal etdiyimiz, orijinal moduldan ayrılmış dəyişəndir.

Beləliklə, sayğacın artırılması modulda onu artıracaq, lakin kopyalanan versiyada onu artırmayacaq. Kopyalanan versiyanı dəyişdirməyin yeganə yolu onu əl ilə artırmaqdır:

counter.counter++; console.log(counter.counter); // 2

Və ES6, idxal edildikdə, modulun canlı yalnız oxunaqlı görünüşünü yaradır:

// lib/counter.js ixrac edək sayğac = 1; ixrac funksiyası increment() ( counter++; ) ixrac funksiyası decrement() ( counter--; ) // src/main.js import * "../../counter"-dən sayğac kimi; console.log(counter.counter); // 1 counter.increment(); console.log(counter.counter); // 2

Maraqlıdır, elə deyilmi? Canlı yalnız oxuna bilən baxışlar haqqında həqiqətən cəlbedici hesab etdiyim şey, funksionallığı itirmədən modullarınızı daha kiçik hissələrə bölməyə imkan verməsidir.

Onları yenidən yerləşdirə və birləşdirə bilərsiniz (yeni layihədə) və heç bir problem yoxdur. Hər şey işləyəcək.

Bir az irəliyə baxmaq: Modulların qurulması

Heyrət! Vay! Zaman necə tez keçdi. Bu, əla səyahət oldu və səmimi qəlbdən ümid edirəm ki, bu məqalə sizə JavaScript-də modulları daha yaxşı başa düşməyi təmin etdi.

Növbəti məqalədə biz modulun bağlanmasını, o cümlədən əsas mövzuları əhatə edəcəyik:

  • Niyə modulları toplayırıq;
  • Müxtəlif montaj yanaşmaları;
  • ECMAScript modul yükləyicisi API;
  • Və daha çox...

Riyazi əməliyyatlara cavabdehdir. Bu yazıda biz bu sinfin sabitlərinə və metodlarına baxacağıq, həmçinin onlardan çətin proqramlaşdırma prosesində necə istifadə edəcəyimizi öyrənəcəyik.

Sabitlərdən başlayaq Riyaziyyat obyekti. Sabitləri nəzərdən keçirin EPI(sizə riyaziyyatdan məlumdur). Gəlin onları dərhal çıxaraq:

Document.write(Math.E);
sənəd.yaz("
");
document.write(Math.PI);

Bu skripti işlətsəniz, ən populyar riyazi sabitlərdən ikisinin dəyərlərini görəcəksiniz.

İndi üsullara nəzər salaq JavaScript-də riyaziyyat obyekti. Birinci üsuldur abs(x), parametr kimi bir ədəd götürür və modulunu qaytarır. Məsələn, bu kimi:

Var x = -15,2;
sənəd.write(Math.abs(x));

Nəticə rəqəm olacaq " 15.2 ".

Növbəti üsul olacaq təsadüfi(). Təsadüfi bir nömrə yaradan çox məşhur bir üsul 0 - 1. Üstəlik, 0 daxildir və 1 artıq daxil deyil. Gəlin bir nömrə alaq 0-dan 10-a qədər.

Document.write(Math.random() * 10);

Bu xətt nömrəni çıxaracaq 0-dan 10-a qədər(və fraksiya). qeyd edin ki 0 bəlkə a 10 ola bilməz.

Metod sqrt(x)ədədin kvadrat kökünü hesablayır. Tətbiq aydın və çox sadədir:

Document.write(Math.sqrt(9));

Bu misalda skripti işlədikdən sonra nömrəni görəcəyik " 3 ".

Metod log(x)ədədin natural loqarifmini hesablayır.

Document.write(Math.log(Math.E * Math.E));

Cavab təbii ki, " 2 ".

Başqa bir üsul ədədin dərəcəsini nəzərə alır. Metod deyilir pow(x, y). İki parametr götürür, birincisi nömrənin əsasıdır, ikincisi isə onun gücüdür. Sadəcə bir misal:

Document.write(Math.pow(2, 5));

Bu tamamilə məntiqlidir 32 .

Və nəhayət, triqonomitr funksiyalarını yerinə yetirən bir qrup metodu nəzərdən keçirin:

Var x = 0,1;
sənəd.write(Math.sin(x) + "
"); // Ədədin sinüsü
document.write(Math.cos(x) + "
"); // Ədədin kosinusu
document.write(Math.tan(x) + "
"); // ədədin tangensi
document.write(Math.asin(x) + "
"); // ədədin arksinusu
document.write(Math.acos(x) + "
"); // ədədin qövs kosinusu
document.write(Math.atan(x) + "
"); // ədədin qövs tangensi.

Triqonometrik funksiyaların icrasının nəticələrinin birləşməməsi üçün hər icradan sonra yeni bir xəttə keçid olur (
).