Internet Windows Android
Kengaytirish

Ok funksiyalari. ES6

12 javob

Nima bu

Bu strelka funksiyasi. O'q funktsiyalari ECMAscript 6 da kiritilgan qisqa sintaksis bo'lib, u funksiya ifodalarini ishlatishga o'xshash tarzda ishlatilishi mumkin. Boshqacha qilib aytganda, funktsiya (foo) (...) kabi iboralar o'rniga ularni tez-tez ishlatishingiz mumkin. Ammo ular bir qator muhim farqlarga ega. Masalan, ular o'zlarining bu qadriyatlarini bog'lamaydilar (quyida muhokamaga qarang).

Ok funksiyalari ECMAscript 6 spetsifikatsiyasining bir qismidir. Ular hali barcha brauzerlarda qo‘llab-quvvatlanmaydi, lekin Node v da qisman yoki to‘liq quvvatlanadi. 4.0+ va 2018-yildan boshlab koʻpgina zamonaviy brauzerlarda foydalanilmoqda. (Quyida qoʻllab-quvvatlanadigan brauzerlarning qisman roʻyxati keltirilgan).

Mozilla hujjatlaridan:

Ok funksiyasi ifodasi (yog 'o'q funksiyasi sifatida ham tanilgan) funksiya ifodalariga qaraganda qisqaroq sintaksisga ega va bu qiymatni leksik jihatdan bog'laydi (o'zining this , arguments , super , yoki new.target ni bog'lamaydi). Ok funksiyalari har doim anonimdir. Ushbu funktsiya ifodalari usul bo'lmagan funktsiyalar uchun eng mos keladi va ularni konstruktor sifatida ishlatib bo'lmaydi.

Bu strelka funksiyalarida qanday ishlashi haqida eslatma

Ok funksiyasining eng qulay xususiyatlaridan biri yuqoridagi matnda yashiringan:

Ok funksiyasi... buning qiymatini leksik jihatdan bog‘laydi (o‘zining buni bog‘lamaydi...)

Oddiy so'zlar bilan aytganda, bu o'q funktsiyasi bu qiymatni o'z kontekstidan saqlaydi va o'zining this ga ega emasligini anglatadi. An'anaviy funktsiya bu qiymatni qanday aniqlangani va chaqirilganiga qarab mustaqil ravishda bog'lashi mumkin. Bu juda ko'p gimnastikani talab qilishi mumkin, masalan, o'zini = bu; Bunga kirish yoki boshqa funktsiya ichidagi bir funktsiyadan manipulyatsiya qilish uchun va hokazo. Ushbu mavzu bo'yicha qo'shimcha ma'lumot olish uchun Mozilla hujjatlaridagi tushuntirish va misollarga qarang.

Misol kod

Misol (shuningdek, hujjatlardan):

Var a = [ "Biz"quyoshgacha tun bo'yi turamiz", "Biz bir oz ovqat olish uchun tun bo'yi turamiz", "Biz yaxshi dam olish uchun tun bo'yi turamiz", "Biz tun bo'yi turamiz" omadli" ]; // Bu ikki topshiriq ekvivalentdir: // Old-school: var a2 = a.map(function(s)( return s.length )); // ECMAscript 6 strelka funksiyalari yordamida var a3 = a.map (s => s.uzunlik); // a2 ham, a3 ham teng bo'ladi

Muvofiqlik eslatmalari

Node-da o'q funksiyalaridan foydalanishingiz mumkin, ammo brauzerni qo'llab-quvvatlash mutlaqo to'g'ri emas.

Ushbu funksiya uchun brauzerni qo'llab-quvvatlash sezilarli darajada yaxshilandi, ammo u hali ham brauzerga asoslangan ilovalar uchun etarlicha keng tarqalmagan. 2017 yil 12 dekabr holatiga ko'ra u joriy versiyalarda qo'llab-quvvatlanadi:

  • Chrome (45+ga nisbatan)
  • Firefox (22+ga qarshi)
  • Edge (12+ga qarshi)
  • Opera (v. 32+)
  • Android brauzeri (47+ versiyasi)
  • Opera Mobile (33+ versiyasi)
  • Android uchun Chrome (versiya 47+)
  • Android uchun Firefox (versiya 44+)
  • Safari (versiya 1 0+)
  • iOS Safari (versiya 10.2+)
  • Internet Samsung (v. 5+)
  • Baidu brauzeri (v. 7. 12+)

Qo'llab-quvvatlanmaydi:

  • IE (11-moddadan oldin)
  • Opera Mini (8.0 versiyasigacha)
  • Blackberry brauzeri (10-versiyagacha)
  • IE Mobile (11-versiyagacha)
  • Android uchun UC brauzeri (11.4 versiyasigacha)
  • QQ (1.2 versiyasigacha)

CanIUse.com saytida ko'proq (va joriy) ma'lumotlarni topishingiz mumkin (hech qanday aloqasi yo'q).

Bu ECMAScript 2015 spetsifikatsiyasining bir qismi boʻlgan oʻq funksiyasi sifatida tanilgan...

var foo = ["a", "ab", "abc"]; var bar = foo.map(f => f.length); console.log(bar); // 1,2,3

Oldingisiga qaraganda qisqaroq sintaksis:

// < ES6: var foo = ["a", "ab", "abc"]; var bar = foo.map(function(f) { return f.length; }); console.log(bar); // 1,2,3

Yana bir ajoyib narsa - leksik bu ... Odatda, siz shunday qilasiz:

funktsiya Foo() ( this.name = name; this.count = 0; this.startCounting(); ) Foo.prototype.startCounting = function() ( var self = this; setInterval(function() ( // bu Oyna, Foo () emas, siz kutganingizdek console.log(this); // // shuning uchun biz buni setInterval() dan oldin self-ga qayta belgilaymiz console.log(self.count); self.count++; ), 1000) ) yangi Foo();

Ammo buni quyidagi o'q yordamida qayta yozish mumkin:

Funktsiya Foo() ( this.name = name; this.count = 0; this.startCounting(); ) Foo.prototype.startCounting = function() ( setInterval(() => ( console.log(bu); // console.log(this.count); // 1, 2, 3 this.count++; ), 1000) ) new Foo();

Bu ECMAScript 6 da kiritilgan "strelka funktsiyasi ifodasi" bo'ladi.

Tarixiy maqsadlar uchun (agar wiki sahifasi keyinroq o'zgartirilsa), bu:

O'q funksiya ifodasi funksiya ifodasiga qaraganda qisqaroq sintaksisga ega va bu qiymatni leksik jihatdan bog'laydi. Ok funksiyalari har doim anonimdir.

Yog 'o'qi funktsiyalari sifatida ham tanilgan. Bu funktsiya() () kabi funksiya ifodalarini yozishning oddiy va tushunarli usuli.

O'q funktsiyalari funksiyalarni belgilashda funktsiya , return va () ga bo'lgan ehtiyojni bartaraf qilishi mumkin. Ular Java yoki Python-dagi lambda iboralariga o'xshash bir chiziqli.

Parametrsiz misol

const queue = ["Deyv", "Sara", "Sharon"]; const nextCustomer = () => navbat; console.log(nextCustomer()); // "Deyv"

Agar siz bir xil o'q funksiyasida bir nechta iboralarni bajarishingiz kerak bo'lsa, bu misol sizdan navbatni jingalak qavslar ichiga qo'yishni talab qiladi () . Bunday holda, qaytarish bayonotini o'tkazib yuborish mumkin emas.

1 parametrli misol

const queue = ["Deyv", "Sara", "Sharon"]; const addCustomer = nom => ( queue.push(name); ); addCustomer("Tobi"); console.log(navbat); // ["Deyv", "Sara", "Sharon", "Tobi"]

Yuqoridagilardan () ni chiqarib tashlashingiz mumkin.

Bitta parametr mavjud bo'lganda, parametr atrofidagi qavslar () qoldirilishi mumkin.

Bir nechta parametrli misol

const addNumbers = (x, y) => x + y console.log(addNumbers(1, 5)); // 6

Foydali misol const fruits = [ (nomi: "Olma", narxi: 2), (nomi: "Bananna", narxi: 3), (nomi: "Armut", narxi: 1) ];

Agar biz har bir mevaning narxini bitta massivda olishni istasak, ES5 da biz quyidagilarni qila olamiz:

Mevalar.xarita(funksiya(meva) ( meva.narxni qaytarish; )); //

ES6-da yangi o'q funktsiyalari bilan biz buni yanada ixcham qilishimiz mumkin:

Fruits.map(meva => meva.narxi); //

O'q funktsiyalari haqida ko'proq ma'lumotni topishingiz mumkin.

Brauzer mosligi
  • IE: hali qo'llab-quvvatlanmaydi
  • Edge: 12+ (barcha versiyalar)
  • Firefox: 22+
  • Chrome: 45+
  • Safari: 10+
  • iOS Safari: 10.2+
  • Android brauzeri: 56+

Brauzer mosligi haqida qo'shimcha ma'lumot olish uchun tashrif buyuring

Boshqalar aytganidek, bu funksiyalarni yaratish uchun yangi sintaksis.

Biroq, bu turdagi funktsiyalar odatdagidan farq qiladi:

    Ular bu qiymatni bog'laydilar. Spetsifikatsiya tushuntirganidek,

    ArrowFunction argumentlar, super, bu yoki new.target uchun mahalliy ulanishlarni aniqlamaydi. ArrowFunction ichidagi argumentlarga , super , this yoki new.targetga har qanday havola leksik muhitdagi bog'lanishni hal qiladi. Odatda bu funktsional muhit darhol funktsiya bo'ladi.

    ArrowFunction super ga havolalarni o'z ichiga olishi mumkin bo'lsa ham, 4-bosqichda yaratilgan funktsiya ob'ekti MakeMethodni bajarish orqali usulga aylantirilmaydi. Super-ga murojaat qiluvchi ArrowFunction har doim strelka bo'lmagan funksiya ichida bo'ladi va super-ning zaruriy amalga oshirilishiga ArrowFunction funksiyasi ob'ekti tomonidan ushlangan doirada kirish mumkin.

  • Ular konstruktor bo'lmaganlar.

    Bu shuni anglatadiki, ularda ichki [] usuli yo'q va shuning uchun misol qilib keltirish mumkin emas

    Var f = a => a; f(123); // 123 yangi f(); // TypeError: f konstruktor emas

O'q bilan oddiy CRUD misolini qo'shish

//Arrow Function var customers = [ (ism: "Dave", aloqa: "9192631770" ), (ism: "Sara", aloqa: "9192631770" ), (ism: "Axil", aloqa: "9928462656" )] , // Param yo'q READ getFirstCustomer = () => ( console.log(this); mijozlarni qaytarish; ); console.log("Birinchi mijoz"+JSON.stringify(getFirstCustomer())); // "Dave" //1 Param SEARCH getNthCustomer = index=>( if(index>customers.length) ( "Bunday narsa yo'q" qaytish; ) else( mijozlarni qaytarish; ) ); console.log("Ninchi mijoz - " +JSON.stringify(getNthCustomer(1))); //2params ADD addCustomer = (ism, kontakt)=> customer.push(( "ism": ism, "kontakt":kontakt )); addCustomer("Hitesh","8888813275"); console.log("Qo'shilgan mijoz"+JSON.stringify(mijozlar)); //2 parametr YANGILANISH updateCustomerName = (indeks, newName)=>(customers.name= newName); updateCustomerName(customers.length-1,"HiteshSahu"); console.log("Yangilangan mijoz "+JSON.stringify(mijozlar)); //1 parametr DELETE removeCustomer = (customerToRemove) => customers.pop(customerToRemove); RemoveCustomer(getFirstCustomer()); console.log("O'chirilgan mijoz "+JSON.stringify(mijozlar));

Boshqa barcha javoblar singari, bu ES2015 funksiyasi sintaksisining bir qismidir. Xususan, bu operator emas, bu parametrlarni tanadan ajratuvchi token tokeni: ArrowFunction: ArrowParameters => ConciseBody . Masalan. (params) => ( /* tana */ ) .

Javascriptda => belgisi o'q funksiyasi ifoda belgisidir. O'q funktsiyasi ifodasi o'ziga xos bu bog'lanishga ega emas va shuning uchun konstruktor funksiyasi sifatida foydalanilmaydi. Masalan:

var so'zlari = "tashqi ob'ektdan salom"; let obj = ( so'zlar: "ob'ekt ichidan salom", talk1: () => (console.log(this.words)), talk2: function () (console.log(thhis.words)) ) obj.talk1( ); // o'ziga xos bu bog'lanishga ega emas, bu === oyna obj.talk2(); // o'ziga xos bu bog'lanishga ega, bu obj

Ok funksiyalaridan foydalanish qoidalari:
  • Agar bitta argument bo'lsa, argument qavslarini tashlab qo'yishingiz mumkin.
  • Agar siz ifodani qaytarsangiz va uni xuddi shu qatorda qilsangiz, () va qaytish iborasini qoldirishingiz mumkin

Masalan:

let times2 = val => val * 2; // U bir xil satrda va ifodani qaytaradi, shuning uchun () bajariladi va ifoda aniq qaytariladi // Bundan tashqari, faqat bitta argument mavjud, shuning uchun argument atrofidagi qavslar olib tashlandi console.log(times2(3));

Boshqa javoblardan norozi. 2019/3/13 da eng ko'p ovoz berilgan javob aslida noto'g'ri.

=> nimani anglatishining qisqacha ixcham versiyasi bu funktsiyani yozish va uni joriy funktsiya bilan bog'lash uchun yorliqdir.

Const foo = a => a * 2;

uchun samarali yorliq

Const foo = funktsiya (a) ( a * 2; ).bog'lash (bu);

Siz kesilgan barcha narsalarni ko'rishingiz mumkin. Bizga funktsiya , return , .bind(this) , qavslar yoki qavslar kerak emas

Ok funksiyasining biroz uzunroq misoli bo'lishi mumkin

Const foo = (kenglik, balandlik) => ( const maydoni = kenglik * balandlik; qaytish maydoni; );

Bu shuni ko'rsatadiki, agar bizga bir nechta funktsiya argumentlari kerak bo'lsa, bizga qavslar kerak va agar biz bir nechta ifoda yozmoqchi bo'lsak, jingalak qavslar va aniq qaytish kerak.

.bind qismini tushunish muhim va bu katta mavzu. Bu JavaScript-da nimani anglatishi bilan bog'liq.

BARCHA funktsiyalarda bu nomli yashirin parametr mavjud. Funktsiyani chaqirishda bu qanday o'rnatilishi funksiya qanday chaqirilishiga bog'liq.

qabul qilish

foo() funktsiyasi ( console.log(this); )

Agar siz uni yaxshi deb chaqirsangiz

Funktsiya foo() ( console.log(this); ) foo();

bu global ob'ekt bo'ladi.

Agar siz qattiq rejimda bo'lsangiz

"qat'iy foydalaning"; funksiya foo() ( console.log(this); ) foo(); // yoki funksiya foo() ( "qat'iy foydalanish"; console.log(this); ) foo();

Belgilanmagan bo'ladi

Buni to'g'ridan-to'g'ri qo'ng'iroq yoki ariza orqali o'rnatishingiz mumkin

Funktsiya foo(msg) ( console.log(msg, this); ) const obj1 = (abc: 123) const obj2 = (def: 456) foo.call(obj1, "salom"); // chop qiladi Salom (abc: 123) foo.apply(obj2, ["salom"]); // Salom chop etadi (def: 456)

Buni nuqta operatori yordamida ham aniq belgilashingiz mumkin.

Funktsiya foo(msg) ( console.log(msg, this); ) const obj = ( abc: 123, bar: foo, ) obj.bar("Hola"); // Hola chop etadi (abc:123, bar: f)

Muammo siz funktsiyadan qayta qo'ng'iroq yoki tinglovchi sifatida foydalanmoqchi bo'lganingizda paydo bo'ladi. Siz sinf yaratyapsiz va sinfning namunasiga kiradigan qayta qo'ng'iroq sifatida funktsiyani tayinlashni xohlaysiz.

Class ShowName ( konstruktor(nom, elem) ( this.name = name; elem.addEventListener("click", function() ( console.log(this.name); // ishlamaydi )); ) )

Yuqoridagi kod ishlamaydi, chunki element hodisani ko'tarib, funktsiyani chaqirganda, bu qiymat sinfning namunasi bo'lmaydi.

Ushbu muammoni hal qilishning keng tarqalgan usullaridan biri .bind dan foydalanishdir

Class ShowName ( konstruktor(nom, elem) ( this.name = name; elem.addEventListener("click", function() ( console.log(this.name); ).bind(this); // ( console.log (bu.name); ))) ) )

bog'lash yangi funktsiyani samarali qiladi. Agar bind mavjud bo'lmasa, siz o'zingizni shunday qilishingiz mumkin

Function bind(funcitonToBind, valueToUseForThis) ( return function(...args) ( functionToBind.call(valueToUseForThis, ...args); )

Spread operatorisiz eski JavaScript-da bu shunday bo'lar edi

Function bind(funcitonToBind, valueToUseForThis) ( return function() ( functionToBind.apply(valueToUseForThis, argumentlar); )

Kodni tushunish yopilishni tushunishni talab qiladi, lekin bog'lashning qisqa versiyasi har doim asl funktsiyani unga bog'langan ushbu qiymat bilan chaqiradigan yangi funktsiyani yaratadi. Ok funksiyasi xuddi shu ishni bajaradi, chunki ular bog'lash uchun yorliqdir (bu)

(=>) belgisi bilan ifodalangan funksiya strelkasi anonim funksiyalar va usullarni yaratishga yordam beradi. Bu qisqaroq sintaksisga olib keladi. Misol uchun, quyida ikkita raqamning qo'shilishini qaytaradigan oddiy Qo'shish funktsiyasi mavjud.

Funktsiya Qo'shish(1-raqam, 2-raqam)( 1-raqam + 2-raqamni qaytarish; )

Yuqoridagi funksiya quyida ko'rsatilgandek Arrow sintaksisi yordamida qisqartiriladi.

Yuqoridagi kod yuqoridagi rasmda ko'rsatilganidek, ikki qismdan iborat:

Kirish: - Bu bo'lim anonim funksiya uchun kirish parametrlarini belgilaydi.

Mantiq: - Bu bo'lim "=>" belgisidan keyin keladi. Ushbu bo'limda haqiqiy funktsiyaning mantig'i mavjud.

Ko'pgina ishlab chiquvchilar o'q funktsiyasi sintaksisni qisqartiradi, soddalashtiradi va shuning uchun kodingizni o'qilishi mumkin deb hisoblaydi.

Agar siz yuqoridagi gapga ishonsangiz, sizni ishontirib aytamanki, bu afsona. Agar bir lahza o'ylab ko'rsangiz, nomi bilan to'g'ri yozilgan funksiya o'q belgisi yordamida bir qatorda yaratilgan sirli funktsiyalarga qaraganda ancha o'qilishi mumkin.

O'q funktsiyasidan asosiy foydalanish kodni chaqiruvchilar kontekstida bajarilishini ta'minlashdir.

Quyida global o'zgaruvchi "kontekst" ni belgilaydigan kodni ko'ring, bu global o'zgaruvchiga boshqa "SomeMethod" usulidan chaqirilgan "SomeOtherMethod" funksiyasi ichida kirish mumkin.

Ushbu SomeMethod mahalliy kontekst o'zgaruvchisiga ega. Endi, SomeOtherMethod "SomeMethod" dan chaqirilganligi sababli, biz uni "mahalliy kontekst" ni ko'rsatishini kutamiz, lekin u "global kontekstni" aks ettiradi.

Var kontekst = "global kontekst"; funktsiya SomeOtherMethod())( alert(this.context); ) funktsiya SomeMethod())( this.context = "mahalliy kontekst"; SomeOtherMethod(); ) var instance = new SomeMethod();

Ammo qo'ng'iroqni o'q funktsiyasi bilan almashtirsangiz, u "mahalliy kontekst" ni ko'rsatadi.

Var kontekst = "global kontekst"; funktsiya SomeMethod())( this.context = "mahalliy kontekst"; SomeOtherMethod = () => ( alert(this.context); ) SomeOtherMethod(); ) var instance = new SomeMethod();

Men sizga ushbu havolani (JavaScript-dagi strelka funksiyasi) o'qib chiqishingizni maslahat beraman, u barcha javascript kontekst stsenariylarini tushuntiradi va qaysi hollarda qo'ng'iroq qiluvchining konteksti hurmat qilinmaydi.

Siz demoni ham ko'rishingiz mumkin Ushbu YouTube videosida javascript bilan o'q funktsiyalari, Bu kontekst atamasini amalda ko'rsatadi.

JavaScript "this" kalit so'zi haqida: tushuntirishlar bilan foydalanish xususiyatlari

Buning siri

Uzoq vaqt davomida bu kalit so'z men uchun sir bo'lib qoldi. Bu kuchli vosita, lekin uni tushunish oson emas.

Java, PHP yoki boshqa har qanday oddiy til nuqtai nazaridan, bu sinf usulidagi joriy ob'ektning namunasi sifatida qaraladi, ko'proq va kam emas. Ko'pincha uni usuldan tashqarida qo'llash mumkin emas va bu yondashuv noto'g'ri tushunilmaydi.

JavaScript-da bu funksiyaning joriy bajarilish konteksti. Chunki funktsiyani to'rt xil usulda chaqirish mumkin:

  • funktsiya chaqiruvi: alert ("Salom dunyo!"),
  • usul chaqiruvi: console.log ("Salom dunyo!"),
  • konstruktor chaqiruvi: new RegExp("\\d"),
  • bilvosita qo'ng'iroq: alert.call (aniqlanmagan, "Salom dunyo!"),

va ularning har biri o'z kontekstini belgilaydi, bu xatti-harakat Ajam ishlab chiquvchilar kutgan narsaga biroz mos kelmaydi. Bundan tashqari, qat'iy rejim ham ijro kontekstiga ta'sir qiladi.

Bu kalit so'zni tushunishning kaliti, funktsiya qanday chaqirilishini va kontekstga qanday ta'sir qilishini tushunishdir. Ushbu maqolada funktsiya chaqiruvlari, qo'ng'iroqlar bunga qanday ta'sir qilishi va kontekstni aniqlashda keng tarqalgan tuzoqlarni qamrab oladi.

Boshlashdan oldin, keling, bir nechta atamalar bilan tanishaylik:

  • Qo'ng'iroq - bu funktsiya tanasi kodining bajarilishi. Masalan, parseInt funksiyasiga qo'ng'iroq parseInt("15") bo'ladi.
  • Chaqiruvchi kontekst funksiya tanasidagi bu qiymatdir.
  • Funksiya doirasi - bu funksiya tanasi ichidan kirish mumkin bo'lgan o'zgaruvchilar, ob'ektlar va funktsiyalar to'plami.

  • 2.1.
    2.2.
    2.3.

  • 3.1.
    3.2.

  • 4.1.
    4.2.

  • 5.1.
  • BILAN
    6.1.

  • 7.1.
    7.2.
  • Funktsiyani chaqirish

    Funktsiya ob'ekti bo'lgan ifodadan keyin ochiq qavs (, vergul bilan ajratilgan argumentlar ro'yxati va yopish qavs) qo'yilganda funktsiya chaqiruvi amalga oshiriladi, masalan, parseInt("18") . Ifoda usul chaqiruvini amalga oshiradigan myObject.myFunction ga qo'shuvchi bo'lishi mumkin emas. Masalan, .join(",") funksiya chaqiruvi emas, balki usul chaqiruvidir.

    Funktsiya chaqiruvining oddiy misoli:

    Function hello(name) ( "Salom" + name + "!" Qaytish; ) // Funktsiyani chaqirish var message = salom("Dunyo"); console.log(xabar); // => "Salom dunyo!"

    salom("Dunyo") funksiya chaqiruvidir: salom funksiya ob'ekti sifatida qaraladi, undan keyin qavs ichida "Jahon" argumenti keladi.

    Var message = (funksiya(nom) ( "Salom" + nom + "!"; ))("Dunyo"ni qaytaring); console.log(xabar); // => "Salom dunyo!"

    Bu ham funksiya chaqiruvidir: qavslarning birinchi jufti (funktsiya(nom) (...)) funksiya ob'ekti sifatida qaraladi, undan keyin qavslar ichida argument qo'yiladi: ("Dunyo") .

    Bu funktsiyani chaqirganda

    bu funktsiyani chaqirganda global ob'ekt

    Global ob'ekt ish vaqti muhiti bilan belgilanadi. Veb-brauzerda bu oyna obyektidir.

    Funktsiya chaqiruvida bajarilish konteksti global ob'ekt hisoblanadi. Keling, quyidagi funksiya kontekstini tekshiramiz:

    Funktsiya summasi(a, b) ( console.log(this === oyna); // => true this.myNumber = 20; // global ob'ektga "myNumber" xususiyatini qo'shing a + b qaytaring; ) // summa( ) funksiya sifatida chaqiriladi // bu sum() da global obyekt (oyna) console.log(sum(15, 16)); // => 31 console.log(window.myNumber); // => 20

    sum(15, 16) chaqirilganda, JavaScript avtomatik ravishda brauzerdagi oyna bo'lgan global ob'ekt sifatida ishga tushiradi.

    Bu har qanday funktsiya doirasidan tashqarida ishlatilsa (eng tashqi doira: global ijro konteksti), u global ob'ektga ham ishora qiladi:

    Console.log(bu === oyna); // => true this.myString = "Salom Dunyo!"; console.log(window.myString); // => "Salom dunyo!" console.log(bu === oyna); // => rost

    Bu qat'iy rejimda funktsiyani chaqirganda

    Bu qat'iy rejimda funktsiyani chaqirganda aniqlanmagan

    /* jshint esnext: true */ class City ( constructor(name, traveled) ( this.name = name; this.traveled = false; ) travel() ( this.traveled = true; ) ) // Konstruktor chaqiruvi var paris = yangi shahar("Parij", yolg'on); paris.travel();

    new City("Parij") konstruktor chaqiruvidir. Ob'ektni ishga tushirish maxsus sinf usuli bilan boshqariladi: konstruktor , bu yangi yaratilgan ob'ekt.

    Konstruktorni chaqirish konstruktor prototipidan xususiyatlarni meros qilib oladigan yangi bo'sh ob'ektni yaratadi. Konstruktor funksiyasining roli ob'ektni ishga tushirishdan iborat. Ma'lumki, ushbu turdagi qo'ng'iroqning konteksti misol deb ataladi. Bu keyingi bobning mavzusi.

    myObject.myFunction aksessuridan oldin yangi kalit so'z bo'lsa, JavaScript metod chaqiruvi emas, balki konstruktor chaqiruvini amalga oshiradi. Misol tariqasida yangi myObject.myFunction() ni olaylik: birinchi navbatda, extractedFunction = myObject.myFunction aksessuari yordamida funksiya ekstraksiya qilinadi va keyin yangi obyekt yaratish uchun konstruktor sifatida chaqiriladi: new extractedFunction() .

    bu konstruktor chaqiruvida

    bu yangi yaratilgan ob'ekt

    Konstruktor chaqiruvining konteksti yangi yaratilgan ob'ektdir. U konstruktor funktsiyasi argumentidan olingan ma'lumotlar bilan ob'ektni ishga tushirish uchun ishlatiladi.

    Keling, quyidagi misoldagi kontekstni tekshirib ko'ramiz:

    Function Foo () ( console.log(this instanceof Foo); // => true this.property = "Birlamchi qiymat"; ) // Konstruktor chaqiruvi var fooInstance = new Foo(); console.log(fooInstance.property); // => "Standart qiymat"

    new Foo() kontekst fooInstance bilan konstruktor chaqiruvini amalga oshiradi. Ob'ekt Foo ichida ishga tushiriladi: this.property standart qiymatga o'rnatiladi.

    Xuddi shu narsa class dan foydalanganda sodir bo'ladi, faqat konstruktor usulida ishga tushirish sodir bo'ladi:

    /* jshint esnext: true */ class Bar ( constructor() ( console.log(this instanceof Bar); // => true this.property = "Default Value"; ) ) // Konstruktor chaqiruvi var barInstance = new Bar( ); console.log(barInstance.property); // => "Standart qiymat"

    new Bar() bajarilganda, JavaScript bo'sh ob'ekt yaratadi va uni konstruktor usuli kontekstiga aylantiradi. Endi bu orqali xususiyatlarni qo'shishingiz mumkin: this.property = "Standart qiymat" .

    Qopqon: yangi narsalarni qanday unutmaslik kerak

    Ba'zi JavaScript funktsiyalari faqat konstruktor sifatida emas, balki funksiya sifatida ham chaqirilganda misollar yaratadi. Masalan, RegExp:

    Var reg1 = yangi RegExp("\\w+"); var reg2 = RegExp("\\w+"); console.log(reg1 instanceof RegExp); // => true console.log(reg2 instanceof RegExp); // => true console.log(reg1.source === reg2.source); // => rost

    Yangi RegExp("\\w+") va RegExp("\\w+") bajarilganda JavaScript ekvivalent muntazam ifoda obyektlarini yaratadi.

    Ob'ektni yaratish uchun funktsiya chaqiruvidan foydalanish potentsial xavflidir (agar zavod usulini o'tkazib yuborsangiz), chunki ba'zi konstruktorlar new kalit so'zi bo'lmaganda ob'ektni ishga tushirmasligi mumkin.

    Quyidagi misol muammoni ko'rsatadi:

    Function Vehicle(type, wheelsCount) ( this.type = type; this.wheelsCount = wheelsCount; return this; ) // Function invocation var car = Vehicle("Car", 4); console.log (car.type); // => "Avtomobil" console.log(car.wheelsCount); // => 4 console.log(car === oyna); // => rost

    Vehicle - bu kontekst ob'ektining turi va wheelsCount xususiyatlarini o'rnatuvchi funksiya. Vehicle("Avtomobil", 4) bajarilganda, u to'g'ri xususiyatlarga ega avtomobil ob'ektini qaytaradi: car.type "Car" ga teng va car.wheelsCount 4 . Hamma narsa kerakli darajada ishlayapti deb o'ylash oson.

    Biroq, bu funksiya chaqirilganda oyna ob'ektidir va Vehicle("Avtomobil", 4) oyna ob'ektining xususiyatlarini o'rnatadi - ha, nimadir noto'g'ri ketdi. Yangi ob'ekt yaratilmadi.

    Konstruktor chaqiruvi kutilayotganda yangi operatordan foydalanganingizga ishonch hosil qiling:

    Function Vehicle(type, wheelsCount) ( if (!(This instanceof Vehicle)) ( throw Error("Xato: noto'g'ri chaqirish"); ) this.type = type; this.wheelsCount = wheelsCount; buni qaytaring; ) // Konstruktor chaqiruvi var car = new Vehicle("Avtomobil", 4); console.log (car.type); // => "Avtomobil" console.log(car.wheelsCount); // => 4 console.log (Avtomobilning avtomobil namunasi); // => true // Funktsiyani chaqirish. Xato hosil qiladi. var brokenCar = Vehicle("Buzilgan mashina", 3);

    new Vehicle("Car", 4) to'g'ri ishlaydi: new so'zi mavjud bo'lgani uchun yangi ob'ekt yaratiladi va ishga tushiriladi.

    Funktsiya chaqiruviga tekshirish qo'shildi: bu Vehicle namunasi ijro kontekstida to'g'ri ob'ekt turiga ega ekanligini ta'minlash uchun. Agar bu Avtomobil bo'lmasa, xatolik yuzaga keladi. Shunday qilib, agar Vehicle("Broken Car", 3) bajarilsa (yangisiz), unda istisno tashlanadi: Xato: noto'g'ri chaqiruv .

    Bilvosita qo'ng'iroq

    Bilvosita chaqiruv funksiya .call() yoki .apply() usullari bilan chaqirilganda amalga oshiriladi.

    /* jshint esnext: true */ var sumArguments = (...args) => ( console.log(typeof arguments); // => "aniqlanmagan" qaytish args.reduce((natija, element) => natija + element );); console.log(sumArguments.name); // => "" console.log(sumArguments(5, 5, 6)); // => 16

    bu o'q funktsiyasida

    bu strelka funksiyasi aniqlangan kontekstdir

    O'q funksiyasi o'zining bajarilish kontekstini yaratmaydi, lekin buni o'zi aniqlangan tashqi funksiyadan oladi.

    Quyidagi misol kontekst shaffofligini ko'rsatadi:

    /* jshint esnext: true */ class Point ( constructor(x, y) ( this.x = x; this.y = y; ) log() ( console.log(this === myPoint); setTimeout(() => ( console.log(this === myPoint); // => true console.log(this.x + ":" + this.y); // => "95:165" ), 1000); ) ) var myPoint = new Point(95, 165); myPoint.log();

    setTimeout o'q funksiyasini log() usuli bilan bir xil kontekstda (myPoint usuli) chaqiradi. Ko'rib turganimizdek, o'q funktsiyasi o'zi aniqlangan funksiya kontekstini "meros oladi".

    Agar siz ushbu misolda oddiy funktsiyadan foydalanmoqchi bo'lsangiz, u o'z kontekstini yaratadi (oyna yoki aniqlanmagan). Shuning uchun, kod to'g'ri ishlashi uchun kontekstni qo'lda bog'lashingiz kerak: setTimeout(function() (...).bind(this)) . Bu og'ir, shuning uchun o'q funksiyasidan foydalanish osonroq.

    Agar o'q funksiyasi barcha funktsiyalardan tashqarida aniqlangan bo'lsa, uning konteksti global ob'ektdir:

    /* jshint esnext: true */ var getContext = () => ( console.log(this === window); // => true buni qaytaradi; ); console.log(getContext() === oyna); // => rost

    Ok funktsiyasi leksik kontekst bilan bir marta va umuman bog'lanadi. buni kontekstni o'zgartirish usuli yordamida ham o'zgartirib bo'lmaydi:

    /* jshint esnext: true */ var numbers = ; (function() ( var get = () => ( buni qaytaring; ); console.log(this === raqamlar); // => true console.log(get()); // => // Foydalanish .apply() va .call() bilan oʻq funksiyasi console.log(get.call()); // => console.log(get.apply()); // => // console.logni bogʻlash(get) .bind()()); // => )).call(raqamlar);

    .call(raqamlar) yordamida bilvosita chaqirilgan funksiya buni raqamlar qiymatiga o'rnatadi. Get strelka funksiyasi ham raqamlarni shunday qabul qiladi, chunki u kontekstni leksik jihatdan oladi. Get qanday chaqirilmasin, uning konteksti har doim raqamlar bo'ladi. Boshqa kontekst bilan bilvosita qo'ng'iroq qilish (.call() yoki .apply() yordamida), qayta bog'lash (.bind() yordamida) hech qanday ta'sir qilmaydi.

    Ok funksiyasidan konstruktor sifatida foydalanish mumkin emas. Agar siz new get() ga qo'ng'iroq qilsangiz, JavaScript xatoga yo'l qo'yadi: TypeError: get konstruktor emas.

    Pitfall: o'q funktsiyasi bilan usulni aniqlash

    Usulni e'lon qilish uchun o'q funktsiyasidan foydalanishni xohlashingiz mumkin. Etarlicha: ularning deklaratsiyasi odatdagi ifodaga nisbatan ancha qisqaroq: funktsiya (param) (..) o'rniga (param) => (...) .

    Ushbu misol Period klassining format() usulini strelka funksiyasi yordamida aniqlashni ko'rsatadi:

    /* jshint esnext: true */ function Davr (soat, daqiqa) ( this.hours = soat; this.minutes = minut; ) Period.prototype.format = () => ( console.log(bu === oyna) ; // =>

    Format global kontekstda aniqlangan o'q funksiyasi bo'lganligi sababli, bu oyna ob'ektidir. Format walkPeriod.format() ob'ektining usuli sifatida bajarilgan bo'lsa ham, oyna chaqiruvchi kontekst bo'lib qoladi. Buning sababi, o'q funktsiyasi boshqa turdagi qo'ng'iroqlar tomonidan o'zgartirilmaydigan statik kontekstga ega.

    Bu oyna, shuning uchun this.hours va this.minutes aniqlanmagan bo'ladi. Usul "aniqlanmagan soatlar va aniqlanmagan daqiqalar" qatorini qaytaradi, bu esa istalgan natija emas.

    Funktsiya ifodasi muammoni hal qiladi, chunki oddiy funktsiya chaqiruvga qarab kontekstini o'zgartiradi:

    Funktsiya davri (soat, daqiqa) ( this.hours = soat; this.minutes = minut; ) Period.prototype.format = function() ( console.log(this === walkPeriod); // => rost buni qaytaring. soatlar + "soatlar va " + bu.daqiqalar + "daqiqalar"; ); var walkPeriod = new Period(2, 30); console.log(walkPeriod.format());

    walkPeriod.format() - bu walkPeriod konteksti bilan usul chaqiruvi. this.hours 2 qiymatini oladi va this.minutes 30 ni oladi, shuning uchun usul to'g'ri natijani qaytaradi: "2 soat va 30 daqiqa" .

    Xulosa

    Funktsiya chaqiruvi bunga eng katta ta'sir ko'rsatganligi sababli, bundan buyon so'ramang:

    Bu qayerdan keladi?

    va so'rang:

    Funktsiya qanday nomlanadi?

    Va o'q funktsiyasi bo'lsa, so'rang:

    Ok funksiyasi e'lon qilingan bu nima?

    Bunga bunday yondashuv sizni keraksiz bosh og'rig'idan qutqaradi.

    Kontekstlarda chalkashmang! 🙂

    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) => ( ifodalar ) (param1, param2, …, paramN) => ifoda // ekvivalent: => ( qaytaruvchi ifoda; ) // Qavslar mavjud boʻlganda ixtiyoriy. 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 to'g'ridan-to'g'ri 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); // Bu alohida emas

    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.

    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, unda, 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:

    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 buyruq satrida (CS) ochamiz. 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 (qaytish 33; ) 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 oyna ob'ekti bo'ladi. 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.

    Odam = ( ism: "Bob", salomlashsin: funktsiya () ( bu = bu; setTimeout(funktsiya () ( 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:

    Grafik misolda o'q 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