Js strelka funktsiyalari. JavaScript "this" kalit so'zi haqida: tushuntirishlar bilan foydalanish xususiyatlari. Ok funksiyalaridan foydalanish qoidalari

Ular juda modaga aylandi, biz ularni barcha yangi maqolalarda ko'ramiz. Va agar siz ularga o'rganmagan bo'lsangiz, o'q funktsiyalarini o'z ichiga olgan zamonaviy (ES6) kodini tushunish qiyin bo'ladi.

Ushbu maqola ularni qachon yoki qanday ishlatishni aytib berish uchun mo'ljallanmagan. Men yangi sintaksisni birinchi marta ko'rayotganlar uchun tushuntirishga harakat qilaman. Siz uni ishlatasizmi yoki yo'qmi muhim emas, lekin ertami-kechmi siz hali ham biror joyda duch kelasiz. Shuning uchun bu yangi sintaksisning mexanikasini tushunish yaxshiroqdir.

Mana kichik bir misol:

Const addOne = funktsiya(n) (qaytish n + 1; )

Yuqoridagi kodni quyidagicha yozish mumkin:

Const addOne = (n) => (qaytish n + 1; )

Yoki, bu holda, undan ham qisqaroq:

Const addOne = (n) => n + 1;

Ikkinchi misolda ( ... ) jingalak qavslar qo'llaniladi, lekin u faqat bitta kod qatori bo'lgani uchun uchinchi misolda ko'rinib turganidek, jingalak qavslar o'tkazib yuborilishi mumkin va qaytish nazarda tutiladi.

Bitta parametr

Agar o'q funksiyasi bitta parametrga ega bo'lsa, qavslar olib tashlanishi mumkin:

// edi: someCallBack((natijalar) => ( ... )) // Hozir: someCallBack(natijalar => ( ... ))

Ammo, agar parametrlar bo'lmasa, siz ochish va yopish qavslaridan foydalanishingiz kerak:

SomeCallBack(() => ( ... ))

Qayta qo'ng'iroq qilish funktsiyalari

Funktsiya strelkalari, ayniqsa, qayta qo'ng'iroqlar uchun foydalidir. JavaScript-ni yaxshi biladiganlar uning leksik ko'lamini yaxshi bilishadi, bu juda toza, ammo shunga o'xshash hiyla-nayranglarni amalga oshirishi mumkin ( bu):

Var_this = bu; someCallBack(function() ( _this.accessOuterScope(); ))

Bu "_this" ning bir nechta o'zgarishlari mavjud (masalan, "o'zini" yoki "bu"), lekin g'oya bir xil. Qayta qo'ng'iroq qilish funktsiyalarida biz tashqi miqyos versiyasiga kirishimiz kerak, ammo g'oya bir xil. Qayta qo'ng'iroq qilish funksiyalarida bizga tashqi miqyosdagi this versiyasiga kirish kerak bo'ladi, bu endi oldingisidan farq qiladi, chunki biz qayta qo'ng'iroq qilish funksiyasi haqida gapiramiz.

Yordamida strelka funktsiyalari, biz "blok doirasi" va "bu" ni olamiz, bu ikkala holatda ham bir xil "bu". Bu shuni anglatadiki, yuqoridagi kodni _this = this holda qayta yozish mumkin:

SomeCallBack(() => ( this.accessOuterScope(); ))

"O'ram"

Keling, voqea sodir bo'lgan Reactdagi kabi vaziyatni tasavvur qilaylik onClick doSomething() , () ni chaqirishi kerak, lekin doSomething() ga argumentlarni ham yuborishi kerak (masalan, ID). Bu misol aslida ishlamaydi:

Ba'zi foydalanuvchi)))

Kod ishga tushadi, lekin texnik jihatdan sahifa yuklanganda darhol doSomething() ni chaqiradi. Ushbu muammoni hal qilish uchun ba'zi ishlab chiquvchilar o'rash funktsiyasiga murojaat qiladilar:

Const User = React.createClass(function() ( render: function() ( Qaytish Ba'zi foydalanuvchi), onClick: function() ( doSomething(this.props.userId); ) ))

this.onClick-da qavsning yo'qligi bu funksiya chaqiruvi emas, balki oddiygina funksiya havolasi ekanligini anglatadi.

OnClick() funksiyasi endi doSomething() uchun o'ramga o'xshaydi. O'q funktsiyalari bilan siz ushbu turdagi "o'rash" ni yaratishingiz mumkin:

Const User = React.createClass(function() ( render: function() (qaytish doSomething(this.props.userId))>Ba'zi foydalanuvchi )))

Shu bilan bir qatorda, biz .bind() dan ham foydalanishimiz mumkin, bu hech qanday o'rashni talab qilmaydi (strelka funktsiyalari yoki boshqa narsalar):

Const User = React.createClass(function() ( render: function() ( Ba'zi foydalanuvchini qaytarish ) ))

O'q funktsiyalari uchun brauzerni qo'llab-quvvatlash

Agar sizga boshqa brauzer yordami kerak bo'lsa oxirgi versiyalari Chrome Va Firefox, foydalaning Babel transpiler siz yozgan ES6 kodini ES5 ga aylantirish uchun.

ES6 funksiyalarni yaratishning yangi usuliga ega - Arrow => operatoridan foydalanish. Bunday funksiyalar strelkali funksiyalar deyiladi. Ular yanada ixcham sintaksisni taklif qilishadi. Ularning nomi yo'q va ular bu bilan boshqacha ishlaydi.

Biz qiladigan birinchi narsa - fayllarni kuzatib boradigan va ular o'zgarganda yangi versiyalarni yaratadigan Babel skriptini ishga tushirish.

Loyiha papkasini oching buyruq qatori(KS). Buyruqni kiriting:

Va Enter tugmasini bosing

Src papkasida biz arr.js faylini yaratamiz va uni darhol index.html faylida ko'rsatamiz.

</skript>

Brauzerlarning so'nggi versiyalari transpilyatsiyasiz o'q funksiyalarini qo'llab-quvvatlaydi va mening brauzerim ulardan biri.

Ikki sonni qo‘shib, ularning yig‘indisini qaytaruvchi funksiya yozamiz. Funktsiyani add deb ataymiz.

Funktsiyani qo'shish (x, y) ( x + y qaytish; ) console.log (qo'shish (3, 6));

Konsolda biz natijani ko'ramiz - 9

Endi bu funksiyani strelka funksiyasiga aylantiramiz.

Keling, funktsiya so'zini olib tashlaymiz, funktsiya nomini olib tashlang va jingalak qavslarni olib tashlang va so'z - qaytish . Parametrlardan so'ng biz o'qni qo'yamiz.

= (x, y) => x + y qo'shilsin; console.log (qo'shish (4, 6));

typeof operatori yordamida add o'zgaruvchining turiga qarasangiz:

Console.log(typeof(add));

Buni biz funktsiya konsolida ko'ramiz

Demak, strelka funksiyalari oddiy funksiyalardir. Buni transpilyatsiya qilingan kodga qarab tekshirishingiz mumkin.

"qat'iy foydalaning"; var _typeof = typeof Symbol === "funktsiya" && typeof Symbol.iterator === "belgi" ? funktsiya (obj) ( return typeof obj; ) : function (obj) ( return obj && typeof Symbol === "funktsiya" && obj.constructor === Symbol && obj !== Symbol.prototype ? "ramz" : typeof obj ;); var add = funktsiya add(x, y) ( qaytish x + y; ); console.log (qo'shish (4, 6)); console.log(typeof add === "aniqlanmagan" ? "aniqlanmagan" : _typeof(qo'shish));

Babel bizning kodimizni oddiy funktsiya ifodasiga aylantirganini ko'rishimiz mumkin.

Berilgan sonni kvadratga aylantiruvchi oddiy funksiya yozamiz.

= (x, y) => x + y qo'shilsin; console.log (qo'shish (4, 6)); console.log(typeof(qo'shish)); let kvadrat = funktsiya (a) ( a * a; qaytaring; ) console.log (kvadrat (4));

Keling, konsolni ko'rib chiqaylik:

Ok funksiyasi quyidagicha ko'rinadi:

Kvadrat = x => x * x;

Agar o'q funktsiyasi faqat bitta parametrni olsa, uni qavs ichiga olishning hojati yo'q!

Hech qanday parametr qabul qilmaydigan funksiya yozamiz.

GivNumer () funksiyasi (33 qaytish; ) console.log(givNumer ());

Bu funksiya shunchaki konsolda 33 raqamini chop etadi.

GivNumer = () => 33; console.log(givNumer());

Hech narsa qaytarmaydigan funksiya yarataylik. U shunchaki brauzer konsolida xabarni ko'rsatadi.

Log = function () ( console.log("Salom Dunyo!"); ); log();

Oʻzgartirish:

Let log = () => console.log("Salom Dunyo!!!"); log();

Tanasi ikki qatordan iborat bo‘ladigan funksiya yarataylik.

Funktsiya ikkita parametrni oladi. Funktsiya tanasida o'zgaruvchi yarataylik. Shundan so'ng biz natijani qaytaramiz.

Mult = funktsiya (a, b) bo'lsin ( natija = a * b; natijani qaytarish; ) console.log(mult (4, 5));

Agar o'q funktsiyasida bir nechta qatorlar mavjud bo'lsa, unda jingalak qavslar kerak - ()! Va qaytish kalit so'zidan foydalanib, bu funktsiya nimani qaytarishini aniqlang

Oʻzgartirish:

Mult = (a, b) => ( natija = a * b; natijani qaytarish; ) console.log(mult (4, 5));

Endi ob'ektning literalini qaytaradigan funksiya yaratamiz:

Let literal = function () ( return (ism: "John"); ) console.log (literal ());

Konsolda biz quyidagilarni ko'ramiz:

Keling, ob'ektning literalini qaytaradigan o'q funktsiyasini yaratishga harakat qilaylik.

Shuni esda tutish kerakki, agar strelka funktsiyasi ob'ektni to'g'ridan-to'g'ri qaytarsa, qavslar kerak bo'ladi - ()

Ob'ektni literalni qaytaruvchi o'q funksiyasi:

Literal = () => ((nomi: "Jon") bo'lsin); console.log(literal());

Endi strelka funksiyasidan IIFE - Darhol chaqirilgan funksiya ifodasi sifatida foydalanishga harakat qilaylik

Qisqacha aytganda, bu deklaratsiyadan so'ng darhol bajariladigan funksiya

Bu shunday ko'rinadi:

(funktsiya () ( console.log("IIFE"); ))();

IIFE o'q funktsiyasi quyidagicha ko'rinadi:

(() => console.log("IIFE"))();

Ok funksiyalarining muhim xususiyati shundaki, strelka parametrlardan keyin darhol kelishi kerak!

Siz shunchaki uni olib, pastdagi qatorga o'tkaza olmaysiz. Bu xato beradi!

Ok funksiyalarining amaliy qo'llanilishi. Ok funksiyalaridan massivlar bilan foydalanish juda qulay.

Keling, bir nechta raqamlar bilan massiv yarataylik va uni raqamlar deb ataymiz. O'ylaymanki, siz massivlarda massivni takrorlash, uni filtrlash va h.k. imkonini beruvchi foydali usullar mavjudligini bilasiz.

Keling, barcha massiv o'zgaruvchilari yig'indisini hisoblaylik. Buning uchun men boshqa o'zgaruvchini e'lon qilaman - sum = 0;

Keling, har bir massivda mavjud bo'lgan forEach() usulidan foydalanamiz, biz elementlarni takrorlaymiz va yig'indiga qo'shamiz.

Raqamlar = bo'lsin; yig'indisi = 0; raqamlar.forHar(funksiya(num) ( summa += son; )); console.log(sum);

Konsolda biz 55 ni ko'ramiz. Bu funksiyani strelka funksiyasiga aylantiramiz: numbers.forEach(num => sum += num); console.log(sum);

Shunday qilib, ilgari bizdan uchta chiziqni olgan narsa endi bittasini oladi.

Shuningdek, massivning har bir elementini kvadratga solishimiz mumkin.

Kvadrat = raqamlar bo'lsin.map(n => n * n); console.log(kvadrat);

Ok funksiyalari va bu. Buning uchun men shaxs o'zgaruvchisida saqlaydigan ob'ekt literalini yarataman.

Shaxs ob'ekti "Bob" qiymatiga ega nom xususiyatiga va "Salom" qiymatiga ega bo'lgan salomlashish xususiyatiga ega bo'ladi. Biz salomlashishni konsolga chop etamiz va bundan maqsadni ham ko'rib chiqamiz.

Shaxs = ( ism: "Bob", salomlashsin: function () ( console.log("Salom! Mening ismim " + this.name); console.log(bu); ) ); odam.salom();

Brauzer konsolida biz salomlashishni va ob'ektning o'zini ko'ramiz.

Endi biz funktsiyani o'q bilan almashtiramiz va bu bilan nima sodir bo'lishini ko'ramiz.

Shaxs = (ism: "Bob", salomlashsin: () => ( console.log("Salom! Mening ismim " + this.name); console.log(bu); ) ); odam.salom();

Endi biz nomning qiymatini olmadik va buning qiymati window !

Lekin nima uchun? Gap shundaki, buning qiymati funktsiya e'lon qilingan kontekstdan olingan. ! Bu funktsiya qayerda bajarilishidan qat'iy nazar. Buni rasmda ko'rish mumkin:

Bizda dastur bor.

Hozircha unda oyna ob'ektidan boshqa hech narsa yo'q. Shaxs ob'ekti qo'shildi. E'tibor bering, biz usul uchun o'q funktsiyasidan foydalanamiz. Aytganimizdek, buning qiymati kontekstdan olinadi. Kontekst - bu atrof-muhit. Bunda shaxs ob'ektining muhiti, uning barcha xossalari va usullari bo'ladi oyna obyekti. Va agar buning qiymati kontekstdan olingan bo'lsa, u holda bu oyna ob'ektiga ishora qiladi.

Agar biz muntazam funktsiyani ko'rib chiqsak, bu shaxs ob'ektining o'ziga tegishli ekanligini bilamiz. Siz so'rashingiz mumkin, nima uchun o'q funktsiyalaridagi bu qiymat kontekstdan olingan? Va javob juda oddiy - ular buni shunday qilishdi! :-) Gap shundaki, o'q funktsiyalari boshqa vaziyatdagi muammolarni hal qilish uchun yaratilgan. Keling, bir misolni ko'rib chiqaylik. Muammoni ko'rish uchun biz o'q funksiyamizga qaytamiz.

Shaxs = ( ism: "Bob", salomlashsin: function () ( console.log("Salom! Mening ismim " + this.name); console.log(bu); ) );

Tasavvur qilaylik, bizning Bob juda band va o'z ishini yakunlash uchun bir necha soniya kerak bo'ladi. 2 soniya kuting. setTimeout() funksiyasidan foydalanib simulyatsiya qilamiz; .Bu funksiya birinchi parametr sifatida funktsiyani va ikkinchi parametr sifatida kutish uchun millisekundlar sonini oladi.

Shaxs = ( ism: "Bob", salomlashsin: funktsiya () ( setTimeout(funktsiya () ( console.log("Salom! Mening ismim " + this.name); console.log(bu); ), 2000) ;))) odam.salom();

Agar sizda JavaScript bilan tajribangiz bo'lsa, muammo nimada ekanligini tushunasiz deb o'ylayman. Qanday bo'lmasin, brauzerda nima bo'lishini ko'rib chiqaylik. Aniq ikki soniyadan so'ng biz ushbu rasmni brauzerda ko'ramiz.

Lekin nima uchun? Agar siz bizning kodimizga qarasangiz, taxmin qilish mantiqiy. Bu shaxs ob'ektiga ishora qiladi, chunki biz muntazam funktsiyadan foydalanamiz. Gap shundaki, setTimeout() oyna obyektiga tegishli. Agar siz buni quyidagicha yozsangiz: window.setTimeout() , unda bu nimaga tegishli deb o'ylaysiz? Va konsolda biz bir xil natijaga erishamiz! ES5 da ushbu muammoni hal qilishning bir necha yo'li mavjud. Biz eng keng tarqalganini ko'rib chiqamiz: setTimeout() dan oldin men boshqa o'zgaruvchini e'lon qilaman va uni qiymat sifatida belgilayman. Endi esa funktsiya tanasida bu o‘rniga shuni ko‘rsatamiz.

Shaxs = ( ism: "Bob", salomlashsin: funktsiya () ( bu = this; setTimeout(function () ( console.log("Salom! Mening ismim " + that.name); console.log(bu) ; ), 2000); ) ); odam.salom();

Endi, yopilish tufayli biz setTimeout() ga yuboradigan funksiya o'zgaruvchiga kirish huquqiga ega bo'ladi, uning qiymati bu bo'ladi, ya'ni bu holda, shaxs ob'ekti.

Aniqlik uchun siz bizning bu va bu nimani anglatishini ko'rishingiz mumkin.

Shaxs = ( ism: "Bob", salomlashsin: funktsiya () ( bu = bu; setTimeout(funktsiya () ( console.log("Salom! Mening ismim " + that.name); console.log("Bu is my That = " + that); console.log("It is my This = " + this); ), 2000); ) ); odam.salom();

Biz konsolda tasdiqlashni ko'ramiz:

Ko'ramizki, bu oyna ob'ekti - This = bo'ladi va bu bizning shaxsiy ob'ektimiz - That = bo'ladi.

ES6 da biz ushbu muammoni hal qilish uchun oddiygina o'q funksiyasidan foydalanishimiz mumkin.

Odam = ( ism: "Bob", salomlashsin: funktsiya () ( setTimeout(() => ( console.log("Salom! Mening ismim " + this.name); console.log("Bu mening Bu = " + bu); ), 2000); ) ); odam.salom();

Natijada, biz konsolda ko'ramiz:

IN grafik misol strelka funksiyasi uchun kontekst oyna ob'ekti emas, balki shaxs ob'ekti bo'ladi. shuning uchun bu odamga tegishli bo'ladi.

Bu kabi muammolarni hal qilish uchun ixcham sintaksisga qo'shimcha ravishda o'q funktsiyalari kiritildi.

Malumot uchun, Bobil buni qanday hal qilganini ko'rishingiz mumkin

Var person = (ism: "Bob", salomlashish: function greet() ( var _this = this; setTimeout(function () ( console.log("Salom! Mening ismim " + _this.name); console.log(" Bu mening Bu = "+ _this); ), 2000); ) ); odam.salom(); Babel biz ES5 da ishlatgan usuldan foydalangan. Yagona farq shundaki, biz o'zgaruvchini shunday deb nomladik va Babel uni - _this deb nomladi. Yopish tufayli biz setTimeout-ga yuboradigan funksiya _this o'zgaruvchisiga va natijada shaxs ob'ektiga kirish huquqiga ega bo'ladi.

Menimcha, bu qismning eng qiyin qismi yopilish qanday ishlashini tushunishdir.

Ok funksiyalarining yana bir qancha xususiyatlari:
Siz mening postimda ES6 va o'q funktsiyalari haqida ko'proq ma'lumotni ko'rishingiz mumkin

Hammaga salom! Ushbu maqolada biz ES6 da qanday o'q funksiyalari borligini va ulardan qanday foydalanishni ko'rib chiqamiz.

Ok funksiyalari strelka operatori (=>) yordamida yoziladigan funksiyalardir.

Keling, darhol misolni ko'rib chiqaylik:

= (x, y) => x + y qo'shilsin;
console.log (qo'shish (5, 2));

Ushbu funktsiyani bajarish natijasida biz konsolda 7 raqamini ko'ramiz.

Birinchidan, biz argumentlarni qavs ichida beramiz, keyin strelka belgisini qo'yamiz, so'ngra funksiyaning kodini yozamiz. Bizning holatda, u oddiygina ikkita raqamni oladi va ularni qo'shadi. Nazariy jihatdan, bu ES5 da funksiya ifodasi bilan bir xil. Agar siz Babel yoki shunga o'xshash kompilyatorlardan foydalansangiz, ular katta ehtimol bilan shunday yozadilar:

Var add = funktsiya add(x, y) (
qaytish x + y;
};

Agar funktsiyangiz faqat bitta parametrni olsa, qavslar ixtiyoriy.

Kvadrat = x => x*x;

Bu funksiya faqat bitta argument oladi va berilgan sonni kvadratga aylantiradi.

Parametrsiz funksiya:

func = () => 77;

Agar sizning funktsiyangiz bir nechta satrlarni o'z ichiga olsa, birinchidan, siz jingalak qavslardan foydalanishingiz kerak, ikkinchidan, funktsiya nimani qaytarishini yozishni unutmang, ya'ni. qaytish kalit so'zidan foydalaning.

Ko'paytirilsin = (x, y) => (
natija = x*y;
natijani qaytarish;
};

Agar ob'ektni tom ma'noda qaytarish kerak bo'lsa, uni qavs ichiga o'rashingiz kerak:

getObject = () => (( brend: "BMW" ));

O'z-o'zini chaqirish funktsiyasi quyidagicha ko'rinadi:

Oʻq funksiya ifodasi bu , argumentlar , super yoki new.target kalit soʻzlariga oʻz bogʻlovchilari boʻlmasa ham, muntazam funksiya ifodasiga sintaktik jihatdan ixcham muqobildir. O'q funksiyasi ifodalari usullar sifatida mos emas va ularni konstruktor sifatida ishlatib bo'lmaydi.

Sintaksis Asosiy sintaksis (param1, param2, …, paramN) => ( bayonotlar ) (param1, param2, …, paramN) => ifoda // ekvivalent: => ( qaytaruvchi ifoda; ) // Qavslar mavjud boʻlganda ixtiyoriy boʻladi. faqat bitta parametr nomi: (singleParam) => ( bayonotlar ) singleParam => ( bayonotlar ) // Parametrlari bo'lmagan funksiya uchun parametrlar ro'yxati bir juft qavs bilan yozilishi kerak. () => ( bayonotlar ) Kengaytirilgan sintaksis // Ob'ektning haqiqiy ifodasini qaytarish uchun funktsiya tanasini qavs ichiga kiriting: params => ((foo: bar)) // Dam olish parametrlari va standart parametrlar qo'llab-quvvatlanadi (param1, param2, ...rest) => ( bayonotlar ) (param1 = defaultValue1, param2, …, paramN = defaultValueN) => ( bayonotlar ) // Parametrlar roʻyxatida tuzilmani buzish ham qoʻllab-quvvatlanadi var f = ( = , (x: c) = (x: a + b)) => a + b + c; f(); // 6 Tavsif

O'q funktsiyalarining kiritilishiga ikkita omil ta'sir ko'rsatdi: qisqaroq funktsiyalarga bo'lgan ehtiyoj va bu kalit so'zning xatti-harakati.

Qisqaroq funksiyalar var elements = [ "Vodorod", "Geliy", "Litiy", "Berilliy" ]; // Ushbu bayonot massivni qaytaradi: elements.map (function(element) ( return element.length; )); // Yuqoridagi muntazam funktsiyani elements ostida o'q funksiyasi sifatida yozish mumkin.map((element) => ( return element.length; )); // // Faqat bitta parametr mavjud bo'lganda, biz atrofidagi qavslarni olib tashlashimiz mumkin elements.map (element => ( return element.length; )); // // Agar o'q funksiyasidagi yagona ibora `qaytish` bo'lsa, biz `return` ni olib tashlashimiz va // atrofidagi jingalak qavslarni olib tashlashimiz mumkin elements.map(element => element.length); // // Bunday holda, bizga faqat length xossasi kerak bo'lganligi sababli, biz tuzilmani buzish parametridan foydalanishimiz mumkin: // E'tibor bering, `length` biz olishni istagan xususiyatga mos keladi, ammo // aniq bo'lmagan `lengthFooBArX`. faqat oʻzgartirilishi mumkin boʻlgan oʻzgaruvchining nomi // istalgan yaroqli oʻzgaruvchi nomiga elements.map (((uzunlik:lengthFooBArX )) => lengthFooBArX); // // Ushbu tuzilmani buzuvchi parametr tayinlanishi quyida ko'rsatilganidek ham yozilishi mumkin. Ammo shuni yodda tutingki, // bu misolda biz tuzilgan xususiyatga "uzunlik" qiymatini belgilamaymiz. Buning o'rniga, biz ob'ektdan olmoqchi bo'lgan xususiyat sifatida "length" o'zgaruvchisining to'liq nomi // ishlatiladi. elementlar.xarita ((( uzunlik )) => uzunlik); // Buni ajratib bo'lmaydi

Ok funksiyalaridan oldin har bir yangi funksiya funksiya qanday chaqirilganiga qarab o‘zining ushbu qiymatini belgilagan:

  • Konstruktor misolida yangi ob'ekt.
  • qat'iy rejimda aniqlanmagan funksiya chaqiruvlari.
  • Agar funktsiya "ob'ekt usuli" sifatida chaqirilgan bo'lsa, asosiy ob'ekt.

Bu ob'ektga yo'naltirilgan dasturlash uslubi bilan idealdan kamroq ekanligini isbotladi.

Person() funksiyasi ( // Person() konstruktori ʻbuni’ oʻzining misoli sifatida belgilaydi. this.age = 0; setInterval(function growUp() ( // Qattiq boʻlmagan rejimda growUp() funksiyasi ʻ ni belgilaydi. this` // global ob'ekt sifatida (chunki bu erda growUp() bajariladi.), // Person() konstruktori tomonidan belgilangan `this` //dan farqli. this.age++; ), 1000) ; ) var p = new Person();

ECMAScript 3/5 da bu muammoni yopilishi mumkin bo'lgan o'zgaruvchiga qiymat belgilash orqali hal qilish mumkin edi.

Function Person() ( var that = this; that.age = 0; setInterval(function growUp() ( // Qayta qo'ng'iroq `that` o'zgaruvchisiga ishora qiladi, uning // qiymati kutilgan ob'ekt hisoblanadi. that.age++; ) , 1000); ) "qat'iy foydalanish"; var obj = (a: 10); Object.defineProperty(obj, "b", (ol: () => ( console.log(this.a, typeof this.a, this); // aniqlanmagan "aniqlanmagan" Oyna (...) (yoki global ob'ekt) this.a + 10ni qaytaring; // "Oyna" global ob'ektini ifodalaydi, shuning uchun "this.a" "aniqlanmagan" ni qaytaradi ) );

Yangi operatordan foydalanish

Ok funksiyalarini konstruktor sifatida ishlatib bo'lmaydi va new bilan foydalanilganda xatolikka yo'l qo'yadi.

Var Foo = () => (); var foo = new Foo(); // TypeError: Foo konstruktor emas

Prototip xususiyatidan foydalanish

Ok funksiyalari prototip xususiyatiga ega emas.

Var Foo = () => (); console.log(Foo.prototype); // aniqlanmagan

Yild kalit so'zidan foydalanish

Yeld kalit soʻzidan strelka funksiyasi tanasida foydalanilmasligi mumkin (uning ichida qoʻshimcha oʻrnatilgan funksiyalar ichida ruxsat etilgan hollar bundan mustasno). Natijada, oʻq funksiyalaridan generator sifatida foydalanib boʻlmaydi.

Funktsiya tanasi

O'q funktsiyalari "qisqa tana" yoki odatiy "blok tanasi" bo'lishi mumkin.

Qisqacha tanada faqat ifoda ko'rsatiladi, bu esa yashirin qaytish qiymatiga aylanadi. Blok tanasida siz aniq qaytarish bayonotidan foydalanishingiz kerak.

Var func = x => x * x; // qisqacha tana sintaksisi, nazarda tutilgan "qaytish" var func = (x, y) => ( return x + y; ); // blok tanasi bilan, aniq "qaytish" kerak

Ob'ekt harflarini qaytarish

Esda tutingki, ixcham tana sintaksisi parametrlari => (object:literal) yordamida ob'ekt harflarini qaytarish kutilganidek ishlamaydi.

Var func = () => ( foo: 1 ); // func() chaqiruvi aniqlanmagan natijani qaytaradi! var func = () => ( foo: function() () ); // SyntaxError: funktsiya bayonoti nom talab qiladi

Buning sababi shundaki, qavslar ichidagi kod (()) iboralar ketma-ketligi sifatida tahlil qilinadi (ya'ni foo ob'ekt harfidagi kalit emas, yorliq kabi ko'rib chiqiladi).

Ob'ektni qavs ichiga o'rashingiz kerak:

Var func = () => (( foo: 1 ));

Chiziq uzilishlari

O'q funksiyasi o'z parametrlari va o'q o'rtasida qator uzilishini o'z ichiga olmaydi.

Var func = (a, b, c) => 1; // Sintaksis xatosi: kutilgan ifoda, "=>" oldi

Biroq, kodning chiroyli va bekamu ko'st bo'lishini ta'minlash uchun o'qdan keyin qatorni qo'yish yoki qavslar/qavslar yordamida o'zgartirish mumkin. Argumentlar orasiga qator uzilishlarini ham qo'yishingiz mumkin.

Var func = (a, b, c) => 1; var func = (a, b, c) => (1); var func = (a, b, c) => (qaytish 1 ); var func = (a, b, c) => 1; // hech qanday sintaksis xatosi yo'q

Tahlil qilish tartibi

O'q funksiyasidagi strelka operator bo'lmasa-da, o'q funktsiyalari oddiy funksiyalarga nisbatan operator ustunligi bilan boshqacha ta'sir qiluvchi maxsus tahlil qilish qoidalariga ega.

Qayta qo'ng'iroq qilish; qayta qo'ng'iroq = qayta qo'ng'iroq || funktsiya (); // ok qayta qo'ng'iroq = qayta qo'ng'iroq || () => (); // SyntaxError: noto'g'ri o'q-funktsiya argumentlari qayta qo'ng'iroq = qayta qo'ng'iroq || (() => ()); // Kelishdikmi

Ko'proq misollar // Bo'sh strelka funksiyasi aniqlanmagan qaytariladi let empty = () => (); (() => "foobar")(); // “foobar”ni qaytaradi // (bu Darhol chaqiriladigan funksiya ifodasi) var simple = a => a > 15 ? 15: a; oddiy(16); // 15 oddiy(10); // 10 let max = (a, b) => a > b ? a: b; // Massivlarni oson filtrlash, xaritalash, ... var arr = ; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // var double = arr.map(v => v * 2); // // Ko'proq ixcham va'da zanjirlari va'da qiladi.then(a => ( // ... )).then(b => ( // ... )); // Parametrsiz strelka funktsiyalari, ularni vizual ravishda tahlil qilish osonroqdir setTimeout(() => ( console.log("Men tezroq sodir bo'ladi"); setTimeout(() => ( // chuqurroq kod console.log("Men keyinroq sodir bo'ladi") ; ), o'n bir); Texnik xususiyatlari Spetsifikatsiya holati sharhi
ECMAScript 2015 (6-nashr, ECMA-262)
Standart Dastlabki ta'rif.
ECMAScript oxirgi loyihasi (ECMA-262)
Ushbu spetsifikatsiyadagi "O'q funktsiyasi ta'riflari" ta'rifi.
Qoralama
Brauzer mosligi

Ushbu sahifadagi muvofiqlik jadvali tuzilgan ma'lumotlardan yaratilgan. Agar siz maʼlumotlarga oʻz hissangizni qoʻshmoqchi boʻlsangiz, iltimos, https://github.com/mdn/browser-compat-data manziliga tashrif buyuring va bizga tortish soʻrovini yuboring.

GitHub-da muvofiqlik ma'lumotlarini yangilang

Ish stoli mobil server Chrome Edge Firefox Internet Explorer Opera Safari Android veb-ko'rinishi Android uchun Chrome Android uchun Firefox Android uchun Opera Android uchun Safari iOS uchun Samsung Internet Node.jsOk funksiyalari Parametrlarda keyingi vergul
Chrome toʻliq qoʻllab-quvvatlash 45Edge To'liq qo'llab-quvvatlash HaFirefox to'liq qo'llab-quvvatlash 22

Eslatmalar

To'liq qo'llab-quvvatlash 22

Eslatmalar

Eslatmalar Firefox 39 dan oldin strelka funksiyasi argumentlaridan keyin qator terminatoriga (\n) noto‘g‘ri ruxsat berilgan. Bu ES2015 spetsifikatsiyasiga va () \n => kabi kodga mos kelishi uchun tuzatildi
IE Qo'llab-quvvatlash yo'qOpera to'liq qo'llab-quvvatlash 32Safari to'liq qo'llab-quvvatlash 10WebView Android to'liq qo'llab-quvvatlash 45Chrome Android to'liq qo'llab-quvvatlash 45Firefox Android to'liq qo'llab-quvvatlash 22

Eslatmalar

To'liq qo'llab-quvvatlash 22

Eslatmalar

Eslatmalar Firefox-da o'q funktsiyalarining dastlabki amalga oshirilishi ularni avtomatik ravishda qattiqlashtirdi. Bu Firefox 24 versiyasidan boshlab o'zgartirildi. "Use strict" dan foydalanish; endi talab qilinadi. Eslatmalar Firefox 39 dan oldin strelka funksiyasi argumentlaridan keyin qator terminatoriga (\n) noto‘g‘ri ruxsat berilgan. Bu ES2015 spetsifikatsiyasiga muvofiq tuzatildi va () \n => () kabi kod endi ushbu va keyingi versiyalarda SyntaxError chiqaradi.
Opera Android to'liq qo'llab-quvvatlash 32Safari iOS to'liq qo'llab-quvvatlash 10Samsung Internet Android to'liq qo'llab-quvvatlash 5.0nodejs To'liq qo'llab-quvvatlash Ha
Chrome toʻliq qoʻllab-quvvatlash 58Edge?Firefox to'liq qo'llab-quvvatlash 52IE Qo'llab-quvvatlash yo'qOpera to'liq qo'llab-quvvatlash 45Safari?WebView Android to'liq qo'llab-quvvatlash 58Chrome Android toʻliq qoʻllab-quvvatlash 58Firefox Android to'liq qo'llab-quvvatlash 52Opera Android to'liq qo'llab-quvvatlash 43Safari iOS?Samsung Internet Android To'liq qo'llab-quvvatlash 7.0nodejs To'liq qo'llab-quvvatlash Ha
Legend Toʻliq qoʻllab-quvvatlash Toʻliq qoʻllab-quvvatlash Yoʻq Qoʻllab-quvvatlash yoʻq Moslik nomaʼlum Moslik nomaʼlum Amalga oshirish eslatmalariga qarang. Amalga oshirish eslatmalariga qarang.
  • Oʻquv qoʻllanma

Yangi ECMAScript 6 standartining eng qiziqarli qismlaridan biri bu strelka funksiyalaridir. O'q funktsiyalari, nomidan ko'rinib turibdiki, o'q => ishlatadigan yangi sintaksis bilan belgilanadi. Biroq, mukammal sintaksisga qo'shimcha ravishda, o'q funktsiyalari an'anaviy funktsiyalardan boshqa jihatlari bilan farq qiladi:

  • Leksik bog‘lanish. Qiymatlar maxsus o'zgaruvchilar this , super va argumentlar strelka funksiyalari qanday chaqirilganiga qarab emas, balki ular qanday yaratilganiga qarab belgilanadi.
  • O'zgarmas bu, super va argumentlar. Ushbu o'zgaruvchilarning o'q funktsiyalari ichidagi qiymatlari butun davomida o'zgarishsiz qoladi hayot davrasi funktsiyalari.
  • Ok funksiyalarini konstruktor sifatida ishlatib bo'lmaydi va yangi operator bilan foydalanilganda xatolikka yo'l qo'yadi.
  • Argumentlar o'zgaruvchisining "mahalliy" qiymatining mavjud emasligi.
Bu farqlarni kiritish uchun bir qancha sabablar bor edi. Birinchisi, bog'lash JavaScript-da juda tez-tez ishlatiladi. An'anaviy funktsiyalardan foydalanganda bu qiymatni to'g'ri yo'qotish juda oson, bu kutilmagan oqibatlarga olib kelishi mumkin. Yana bir sabab shundaki, JS dvigatellari ushbu cheklovlar tufayli strelka funktsiyalarining bajarilishini osonlikcha optimallashtirishi mumkin (konstruktor sifatida ishlatilishi mumkin bo'lgan va o'zgartirish bepul bo'lgan an'anaviy funktsiyalardan farqli o'laroq). maxsus o'zgaruvchilar).


Eslatma: Ushbu maqola ECMAScript 6 strelka funktsiyalarini tushunish maqolasining bepul tarjimasi va spetsifikatsiyaning so'nggi loyihasini o'qish (2014 yil 20 yanvar, 22-sonli Rev loyihasi) to'plamidir.

Sintaksis Umuman olganda, o'q funktsiyalari sintaksisi quyidagicha ko'rinadi:

Var fun = (x) => x;
Bu Scala, CoffeeScript va C# dan lambda iboralari sintaksisi kabi tillardagi o'xshash sintaksisga juda o'xshaydi.

O'q funktsiyalari sintaksisi funktsiyani qanday e'lon qilganingizga qarab farq qilishi mumkin. Deklaratsiya har doim argumentlar ro'yxati bilan boshlanadi, undan keyin o'q va funktsiya tanasi keladi. Argumentlar ro'yxati ham, funktsiya tanasi ham siz yozgan narsaga qarab turli shakllarga ega bo'lishi mumkin.

Bitta parametr Bitta argumentni qabul qiladigan va uni oddiygina qaytaradigan o‘q funksiyasini e’lon qilish juda oddiy:

Var refle = qiymat => qiymat; // var reflektsiyasiga ekvivalent = funktsiya (qiymat) (qiymatni qaytarish; )
Agar o'q funksiyasi faqat bitta argumentga ega bo'lsa, uni qavslarsiz e'lon qilish mumkin. O'qdan keyingi funktsiya tanasi ham jingalak qavslarga ega bo'lmasligi va return kalit so'zini o'z ichiga olmaydi.

Bir nechta parametrlar Agar siz bir nechta parametrlarni e'lon qilmoqchi bo'lsangiz, parametrlar ro'yxatini qavs ichiga qo'shishingiz kerak:

Var sum = (1-raqam, 2-raqam) => num1 + son2; // var sum ga ekvivalent = function(num1, num2) ( 1-raqam + son2; );
sum funktsiyasi oddiygina ikkita argument qo'shadi. Oldingi misoldan yagona farq - bu qavslar va vergulning mavjudligi (xuddi an'anaviy funktsiyalarda bo'lgani kabi).

Parametrlar yo'q Xuddi shunday, hech qanday argumentsiz funksiya qavslar ichida bo'sh parametrlar ro'yxatiga ega bo'lishi kerak:

Var sum = () => 1 + 2; // var sum ga ekvivalent = function() (qaytish 1 + 2; );

An'anaviy funktsiya tanasi sintaksisi Agar o'q funksiyasi bir nechta ifodani o'z ichiga olgan bo'lsa, uning tanasi uchun an'anaviy funksiya sintaksisidan foydalanishingiz mumkin. Ya'ni, funktsiyani jingalak qavslarga o'rang va return kalit so'zini qo'shing:

Var sum = (num1, num2) => ( 1-raqamni + 2-raqamni qaytarish; ) // var sumga ekvivalent = funktsiya (1-raqam, 2) ( 1-raqamni + 2-raqamni qaytarish; );
Funksiya tanasi klassik funksiyalar bilan bir xil tarzda qayta ishlanadi, faqat qiymatlar bundan mustasno maxsus o'zgaruvchilar bu , super va argumentlar boshqacha baholanadi.

Ob'ekt harfi Alohida ta'kidlab o'tish kerakki, jingalak qavslarni o'z ichiga olmaydi va shunchaki ob'ekt harfini qaytaradigan funktsiya tanasi qavs ichiga olinishi kerak:

Var getTempItem = id => (( id: id, nomi: "Temp" )); // ekvivalenti var getTempItem = function(id) ( return ( id: id, name: "Temp" ) );
Qavslar ichiga ob'ekt harfini qo'yish tahlilchiga jingalak qavslar funksiya tanasi uchun an'anaviy sintaksisning boshlanishi emas, balki harfning boshlanishi ekanligini aytadi.

Parametrlarning o'zgaruvchan soni O'q funktsiyasi ichida "mahalliy" argumentlar ob'ekti mavjud emasligi sababli (argumentlar qiymati o'q funktsiyasi e'lon qilingan an'anaviy funktsiya argumentlari qiymati bilan leksik jihatdan bog'liq), keyin o'q funksiyalari uchun qolgan naqshdan foydalanishingiz kerak bo'lgan parametrlarning o'zgaruvchan soni tuzilmalarni buzish. Misol:

Var getTempItems = (...dam olish) => dam; // ekvivalenti var getTempItems = function() ( return .slice.apply(arguments) );

Shablonni parametr sifatida buzish Ushbu maqolaning maqsadlari uchun biz tuzilmalarni buzishni hisobga olmaymiz - ular haqida JavaScript-ning keyingi versiyasi bo'lgan ECMAScript 6-ga umumiy nuqtai maqolada o'qishingiz mumkin, garchi bu ma'lumot qisman eskirgan bo'lsa ham.

Oldingi misoldan ko'rinib turibdiki, o'q funktsiyasi faqat bitta argumentga ega bo'lsa ham, foydalanayotganda siz hali ham qavslardan foydalanishingiz kerak. tuzilmalarni buzish funktsiyaning yagona parametri sifatida. Boshqalar bilan misollar andozalar:

Var a = ((a)) => a; var b = ([b]) => b;

Ok funksiyalaridan foydalanish Kontekstni sozlash JavaScript-da keng tarqalgan stsenariylardan biri bu qiymatni funktsiya ichida to'g'ri belgilash (bog'lash). Buning qiymati funktsiya bajariladigan kontekstga qarab o'zgartirilishi mumkinligi sababli, siz butunlay boshqacha narsani nazarda tutganingizda, bitta ob'ektda xatolik bilan harakat qilish mumkin. Quyidagi misolga qarang:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", function(voqea) ( this.doSomething(event.type); // error )); ) , doSomething: function( type) ( console.log("Handling" + type + " for " + this.id) ) );
Yuqoridagi kodda pageHandler obyekti sahifadagi bosishlarni boshqarishi kerak. init() usuli ichki ravishda this.doSomething() deb ataladigan kerakli hodisaga ishlov beruvchini biriktiradi. Biroq, kod to'g'ri ishlamaydi. this.doSomething() ga havola noto'g'ri, chunki bu mo'ljallangan pageHandler o'rniga voqea ishlov beruvchisi ichidagi hujjat ob'ektiga ishora qiladi. Agar siz ushbu kodni ishga tushirishga harakat qilsangiz, hujjat ob'ektida doSomething usuli yo'qligi sababli xatoga duch kelasiz.

Ushbu qiymatni pageHandler obyektiga handleEvent yordamida yoki funksiyadagi standart bind() usulini chaqirish orqali bog‘lashingiz mumkin:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", (funksiya(voqea)) ( this.doSomething(voqe.type); // xato )).bind(bu)) ; ) , doSomething: function(type) ( console.log("Handling" + type + " for " + this.id) ) );
Endi kod mo'ljallanganidek ishlaydi, lekin u yanada og'irroq ko'rinadi. Bundan tashqari, bind(this) ni chaqirib, har safar yangi funktsiya yaratganingizda, uning qiymati pageHandler qiymatiga bog'langan, lekin kod siz xohlagandek ishlaydi.

Ok funktsiyalari muammoni yanada oqlangan tarzda hal qiladi, chunki ular bu qiymat uchun leksik bog'lanishdan foydalanadilar (shuningdek, super va argumentlar ) va uning qiymati o'q funksiyasi yaratilgan joyning qiymati bilan belgilanadi. Masalan:

Var pageHandler = ( id: "123456" , init: function() ( document.addEventListener("click", event => this.doSomething(event.type)); ) , doSomething: function(type) ( console.log( "Ishlash" + this.id uchun "+ type +" ) );
Ushbu misolda ishlov beruvchi this.doSomething() ni chaqiradigan o'q funktsiyasidir. Buning qiymati init() funksiyasidagi va koddagi bilan bir xil bo'ladi bu misolda bind() dan foydalanganga o'xshash to'g'ri ishlaydi. this.doSomething() ga qo'ng'iroq qiymatni qaytaradimi yoki yo'qligidan qat'i nazar, o'q funksiyasining tanasi ichidagi ifodani jingalak qavslar ichiga olish shart emas.

Bundan tashqari, yuqoridagi misol bind() ni chaqirishdan ko'ra samaraliroq, chunki u brauzer uchun quyidagi kod bilan bir xil:

Var pageHandler = ( id: "123456" , init: function() ( var self = this; document.addEventListener("click", function(event) ( return self.doSomething(event.type) )); ) , doSomething: funktsiya(turi) ( console.log("Ko'rish " + type + " uchun " + this.id) ) );
Ya'ni, yaratilish sodir bo'lmaydi yangi xususiyat, bind() chaqiruvida bo'lgani kabi.

Bir nechta qo'ng'iroqlar orasiga kontekstni "tashlash" Shubhasiz, siz bir strelka funktsiyasini boshqasiga joylashtirishingiz va shu bilan ular orqali ushbu qiymatni "tashlashingiz" mumkin:

Var obj = ( arr1: , arr2: ["a", "b", "c"] , birlashtiruvchi: funktsiya(a, b)( a + "|" + b ) , kesishish: function() ( buni qaytaring .arr1.reduce((sum, v1) => // o‘q funksiyasi 1 this.arr2.reduce((sum, v2) => ( // o‘q funksiyasi 2 summa.push(this.concatenate(v1, v2)) qaytish yig'indi; ) , yig'indisi) , )))) var arrSum = obj.intersection();//["1|a", "1|b", "1|c", "2|a", "2|b", "2|c", "3 |a", "3|b", "3|c"]

Argument sifatida foydalaning O'q funktsiyalarining qisqa sintaksisi ularni boshqa funktsiya chaqiruvlariga argument sifatida o'tkazish uchun ideal nomzod qiladi. Misol uchun, agar siz massivni saralashni istasangiz, odatda shunday yozasiz:

Var natija = qiymatlar.sort(funksiya(a, b) (qaytish a - b ));
Oddiy operatsiya uchun juda batafsil. O'q funktsiyasi uchun qisqa yozuv bilan solishtiring:

Var natija = qiymatlar.sort((a, b) => a - b);
array() , map() , reduce() va boshqalar kabi usullardan foydalanish qisqa oʻq funksiyasi sintaksisi yordamida soddalashtirilishi mumkin.

O'q funktsiyalarining boshqa xususiyatlari Garchi o'q funktsiyalari an'anaviy funktsiyalardan farq qilsa-da, ular ba'zi umumiy xususiyatlarga ega:
  • typeof operatori o'q funksiyasi uchun "funksiya" ni qaytaradi
  • Ok funksiyasi ham "sinf" funktsiyasining namunasidir, shuning uchun instanceof an'anaviy funktsiya bilan bir xil ishlaydi.
  • Siz hali ham call() , apply() va bind() usullaridan foydalanishingiz mumkin, lekin ular bu qiymatga ta’sir qilmasligini unutmang.
  • Siz toMethod() usulidan foydalanishingiz mumkin, ammo u super () qiymatini o'zgartirmaydi. toMethod() usuli es6 da kiritilgan va bu maqolada yoritilgan).
An'anaviy funktsiyalardan sezilarli farq shundaki, yangi operator yordamida o'q funksiyasini chaqirishga urinish ish vaqti xatosiga olib keladi.Xulosa Ok funksiyalari ECMAScript 6 ning eng qiziqarli yangiliklaridan biri bo'lib, qisqacha ta'rif sintaksisiga ega bo'lib, uni soddalashtiradi. funksiyalarni parametr qiymati sifatida boshqa funktsiyaga o'tkazish.

Qisqacha sintaksis sizga murakkab narsalarni yanada murakkabroq sodda tarzda yozishga imkon beradi. Masalan, identifikator generatori shunday ko'rinishga ega bo'ladi (bu es5 da ancha batafsil ko'rinadi):

idGen = (start = 0, id = start, reset = (newId = start) => id = newId, keyingi = () => id++) => ((qayta tiklash, keyingi)); let gen = idGen(100); console.log(gen.next(), gen.next(), gen.reset(10), gen.next());//100 101 10 10
Va lug'aviy bog'lanish ishlab chiquvchilar uchun eng katta og'riq va umidsizlik manbalaridan birini yopadi va JS dvigatel darajasida optimallashtirish tufayli ishlashni yaxshilaydi.


Agar siz o'q funksiyalarini sinab ko'rmoqchi bo'lsangiz, yuqoridagi misollarni yoqilgan Firefox konsolida ishga tushirishingiz mumkin bu daqiqa(02.2014 FF28) o'q funktsiyalarini deyarli to'liq qo'llab-quvvatlaydi (FF28 argumentlar qiymatini noto'g'ri hisoblaydi ).

Shuningdek, Traceur onlayn tarjimonida oʻq funksiyalari va boshqa es6 funksiyalarini sinab koʻrishingiz mumkin.

Teglar: teglar qo'shish