js şablonları. Javascript şablonları nədir və onlar nə üçün lazımdır? Dizayn nümunələri nədir və niyə istifadə olunur




Salam, habr!
Mən təəccübləndim ki, mərkəzdə mövzu ilə bağlı ətraflı məqalə yoxdur və bu, məni dərhal bu açıq ədalətsizliyi düzəltməyə sövq etdi.

Veb proqramlarının müştəri tərəfinin getdikcə qalınlaşdığı, biznes məntiqinin qaçılmaz olaraq müştərinin üzərinə süründüyü və node.js-in server texnologiyalarının suverenliyinə getdikcə daha çox müdaxilə etdiyi bir mühitdə insan arxitekturanın dizayn üsulları haqqında düşünməyə bilməz. JavaScript. Və bu məsələdə dizayn nümunələri, şübhəsiz ki, bizə kömək etməlidir - tez-tez rast gəlinən problemlərin həlli üçün şablon üsulları. Nümunələr dəyişikliklər etmək lazım olduqda sizdən ən az səy tələb edən bir memarlıq yaratmağa kömək edir. Ancaq onları panacea kimi qəbul etməməlisiniz, yəni kobud desək, kodun keyfiyyəti "yaxşı deyilsə", sərt kodla və məntiqi müstəqil modullar arasında sıx əlaqələrlə doludursa, heç bir nümunə onu xilas etməyəcək. Ancaq vəzifə miqyaslı bir memarlıq dizayn etməkdirsə, nümunələr yaxşı kömək ola bilər.
Bununla belə, bu məqalə dizayn nümunələri haqqında deyil, onların javaScript-də tətbiqi haqqındadır. Bu məqalənin birinci hissəsində generativ nümunələrin istifadəsi haqqında yazacağam.

Singleton Əgər tapşırıq bu nümunəni bir cümlə ilə təsvir etmək idisə, belə bir şey ortaya çıxacaq: Singleton yalnız bir nümunəyə malik olan bir sinifdir.
Bu nümunəni həyata keçirmək üçün ən sadə və ən bariz JavaScript həlli obyektlərdən istifadə etməkdir:

Var app = ( xüsusiyyət1: "dəyər", xüsusiyyət2: "dəyər", ... metod1: funksiya () ( ... ), ... )

Bu metodun həm üstünlükləri, həm də mənfi cəhətləri var. Təsvir etmək asandır, bir çox insanlar heç bir nümunənin mövcudluğunu dərk etmədən istifadə edirlər və bu yazı forması istənilən JavaScript tərtibatçısına başa düşüləcək. Lakin onun əhəmiyyətli çatışmazlığı da var: singleton modelinin əsas məqsədi qlobal dəyişənlərdən istifadə etmədən obyektə girişi təmin etməkdir və bu üsul yalnız cari əhatə dairəsində tətbiq dəyişəninə girişi təmin edir. Bu o deməkdir ki, biz proqram obyektinə tətbiqin istənilən yerindən yalnız qlobal olduqda daxil ola bilərik. Çox vaxt bu, son dərəcə qəbuledilməzdir; yaxşı JavaScript inkişaf tərzi, lazım olan hər şeyi əhatə edən ən çox bir qlobal dəyişəndən istifadə etməkdir. Bu o deməkdir ki, yuxarıdakı yanaşmanı tətbiqdə ən çox bir dəfə istifadə edə bilərik.
İkinci üsul bir az daha mürəkkəbdir, eyni zamanda daha universaldır:

Function SomeFunction () ( if (typeof (SomeFunction.instance) == "object") ( return SomeFunction.instance; ) this.property1 = "value"; this.property2 = "value"; SomeFunction.instance = this; return this. ; ) SomeFunction.prototype.method1 = funksiya () ( )

İndi istənilən modul sistemdən (məsələn, requirejs) istifadə edərək, proqramımızın istənilən yerində bu konstruktor funksiyasının təsviri olan faylı birləşdirə və yerinə yetirməklə obyektimizə daxil ola bilərik:

Var someObj = new SomeFunction();

Lakin bu metodun öz çatışmazlığı da var: nümunə sadəcə olaraq konstruktorun statik xassəsi kimi saxlanılır ki, bu da hər kəsə onun üzərinə yazmağa imkan verir. İstəyirik ki, istənilən şəraitdə tətbiqimizin istənilən küncündən tələb olunan obyektə daxil ola bilək. Bu o deməkdir ki, nümunəni saxlayacağımız dəyişən özəlləşdirilməlidir və bağlamalar bu işdə bizə kömək edəcəkdir.

Funksiya SomeFunction () ( var instansiya; SomeFunction = funksiya () ( qaytarma nümunəsi; ) this.property1 = "value"; this.property2 = "value"; instance = this; )

Deyəsən, bütün problemlərin həlli budur, amma köhnə problemlərin yerini yeni problemlər tutur. Məhz: nümunə yaradıldıqdan sonra konstruktor prototipinə daxil olan bütün xüsusiyyətlər mövcud olmayacaq, çünki əslində onlar yeni təyin olunmuş konstruktora deyil, köhnə konstruktora yazılacaq. Ancaq bu vəziyyətdən yaxşı bir çıxış yolu var:

Funksiya SomeFunction () ( var misal; SomeFunction = funksiya () ( qaytarma nümunəsi; ) SomeFunction.prototype = bu; instansiya = yeni SomeFunction (); instance.constructor = SomeFunction; instance.property1 = "dəyər"; instance.property2 = " dəyər"; qaytarma nümunəsi; )

Singiltonu təsvir etməyin bu üsulu yuxarıda göstərilən bütün çatışmazlıqlardan məhrumdur və universal istifadə üçün olduqca uyğundur, lakin bağlanmadan istifadə edərək singletonu təsvir etmək üsulları tələblərlə işləməyəcək, ancaq onları bir az dəyişdirsəniz və dəyişəni kənara köçürsəniz. funksiyanın özü tərəfindən müəyyən edilmiş funksiyaya bağlanması, onda problem həll olunacaq:

Define(, function () ( var instance = null; function SomeFunction() ( if (instance) ( return instance; ) this.property1 = "value"; this.property2 = "value"; instance = this; ); return SomeFunction ;)))

Zavod üsulu Zavod metodunun iki əsas məqsədi var:
1) Açıqca konkret siniflərdən istifadə etməyin
2) Tez-tez istifadə olunan obyektin başlanğıc üsullarını birləşdirin
Zavod metodunun ən sadə tətbiqi bu nümunədir:

Funksiya Foo () ( //... ) funksiyası Bar () ( //... ) funksiya zavodu (növ) ( keçid (növ) ( "foo" halı: yeni Foo (); hal "bar": qayıt yeni Bar(); ) )

Müvafiq olaraq, obyektlərin yaradılması belə görünəcəkdir:

Foo = zavod ("foo"); bar = zavod ("bar");

Daha zərif bir həll istifadə edilə bilər:

Funksiya PetFactory() ( ); PetFactory.register = function(ad, PetConstructor) ( if (Funksiya nümunəsinin adı) ( PetConstructor = name; name = null; ) if (!(PetConstructor instanceof Function)) ( atmaq (ad: "Xəta", mesaj: "PetConstructor is funksiya deyil" ) ) this = PetConstructor; ); PetFactory.create = function(petName) ( var PetConstructor = this; if (!(PetConstructor instanceof Function)) ( atmaq (ad: "Xəta", mesaj: "konstruktor "" + petName + "" müəyyən edilməmiş" ) ) yeni PetConstructor qaytarın (); );

Bu halda, biz özümüzü fabrikin yarada biləcəyi siniflərin sayı ilə məhdudlaşdırmırıq, onlardan istədiyimiz qədər çoxunu bu şəkildə əlavə edə bilərik:

PetFactory.register("it", function() ( this.say = function () ( console.log("gav"); ) ));

Və ya bu kimi:

Function Cat() ( ) Cat.prototype.say = function () ( console.log("meow"); ) PetFactory.register(Cat);

Abstract Factory Bir-biri ilə əlaqəli və ya bir-birindən asılı olan obyektlər qrupunu yaratmaq üçün mücərrəd fabrik istifadə olunur.
Tutaq ki, eyni elementlərdən ibarət bir neçə pop-up pəncərəmiz var, lakin bu elementlər fərqli görünür və istifadəçi hərəkətlərinə fərqli reaksiya verir. Bu elementlərin hər biri zavod metodundan istifadə etməklə yaradılacaq, yəni hər bir pop-up pəncərə növünə öz obyekt zavodu lazımdır.
Məsələn, BluePopupFactory fabrikini təsvir edək; o, PetFactory ilə tamamilə eyni quruluşa malikdir, ona görə də təfərrüatları buraxıb sadəcə ondan istifadə edəcəyik.

Funksiya BluePopup () ( //açılan pəncərənin yaradılması) BluePopup.prototype.attach = funksiya (elementlər) ( //pəncərəyə digər ui elementlərinin əlavə edilməsi) BluePopupFactory.register("popup", BluePopup); funksiya BluePopupButton () ( //mavi açılan pəncərə üçün düymənin yaradılması) BluePopupButton.prototype.setText = funksiya (mətn) ( //düymədə mətnin qurulması) BluePopupFactory.register("düymə", BluePopupButton); funksiya BluePopupTitle () ( //mavi pəncərə üçün başlıq yaradılması) BluePopupTitle.prototype.setText = funksiya (mətn) ( //başlıq mətninin qurulması) BluePopupFactory.register("başlıq", BluePopupTitle);

Yəqin ki, interfeys elementlərinə cavabdeh olan bir növ sinifimiz olmalıdır.

Funksiya UI () ( //ui elementlərinə cavabdeh olan sinif)

Və ona createPopup metodunu əlavə edəcəyik:

UI.createPopup = funksiya (zavod) ( var popup = factory.create("popup"), buttonOk = factory.create("button"), buttonCancel = factory.create("button"), title = factory.create(" title"); buttonOk.setText("OK"); buttonCancel.setText("Ləğv et"); title.setText("Adsız"); popup.attach(); )

Gördüyünüz kimi createPopup arqument kimi fabriki götürür, pop-upın özünü və onun üçün başlıq olan düymələri yaradır və sonra onları pəncərəyə əlavə edir.
Bundan sonra bu üsuldan aşağıdakı kimi istifadə edə bilərsiniz:

Var newPopup = UI.createPopup(BluePopupFactory);

Müvafiq olaraq, qeyri-məhdud sayda fabrikləri təsvir edə və növbəti pop-up pəncərəsini yaratarkən sizə lazım olanı keçə bilərsiniz.

Bəzən bir sinfi birbaşa yaratmaq arzuolunmazdır. Sonra biz optimal instansiya mexanizmini seçə bilən generativ nümunələrə müraciət edirik.

Sadə fabrik

Ev tikərkən qapıları özünüz etmək olduqca çətin olacaq, ona görə də onları mağazadan hazır şəkildə alırsınız.

Nümunə Sadə bir fabrik müştərini bu prosesin incəlikləri ilə narahat etmədən tələb olunan nüsxəni istehsal edir.

İcra nümunəsi

Bütün qapılar üçün gizli interfeys yaradaq:

/* Qapı getWidth() getHeight() */ sinif WoodenDoor ( konstruktor(en, hündürlük)( this.width = width this.height = height ) getWidth() ( return this.width ) getHeight() ( return this.height ) )

Onları istehsal edəcək bir fabrik təşkil edəcəyik:

Const DoorFactory = ( makeDoor: (en, hündürlük) => yeni WoodenDoor (en, hündürlük) )

Budur, işləyə bilərsiniz:

Const qapı = DoorFactory.makeDoor(100, 200) console.log("En:", door.getWidth()) console.log("Hündürlük:", door.getHeight())

Obyekt yaratmaq bəzi məntiq tələb edirsə, nümunə faydalıdır. Təkrarlanan kodu ayrıca Sadə Fabrikaya köçürməyin mənası var.

Zavod üsulu

İşə qəbul üzrə menecer müxtəlif vakansiyalar üzrə namizədlərlə işləyir. Hər bir vəzifənin incəliklərini araşdırmaq əvəzinə o, texniki müsahibəni digər mütəxəssislərə həvalə edir.

Bu nümunə konstruktoru lazımsız kodla çirkləndirmədən obyektin müxtəlif variasiyalarını yaratmağa imkan verir.

İcra nümunəsi

Hamburgerin özündən başlayaq:

Class Burger ( constructor(builder) ( this.size = builder.size this.cheeze = builder.cheeze || false this.pepperoni = builder.pepperoni || false this.saltuce = builder. salata || false this.tomato = builder .pomidor || yalan ) )

Və budur İnşaatçı:

Class BurgerBuilder ( constructor(size) ( this.size = size ) addPepperoni() ( this.pepperoni = true return this ) addLettuce() ( this.lettuce = true return this ) addCheeze() ( this.cheeze = true return this ) addTomato() ( this.tomato = true return this ) build() ( new Burger(bu) qaytarın ) )

Voila! Burgerimiz budur:

Const burger = (yeni BurgerBuilder(14)) .addPepperoni() .addLettuce() .addTomato() .build()

Əgər obyekt müxtəlif variasiyalarda mövcud ola bilərsə və ya nümunələşdirmə prosesi bir neçə addımdan ibarətdirsə, Qurucu nümunəsi lazımdır.

Singleton

Ölkədə vahid prezident olmalıdır, əks halda xaos yaranacaq.

Bu nümunə obyekti bükür və onun davranışını dinamik şəkildə dəyişir.

İcra nümunəsi

Məsələn, qəhvə götürək. Müvafiq interfeysi həyata keçirən ən sadə qəhvə:

/* Qəhvə interfeysi: getCost() getDescription() */ class SimpleCoffee( getCost() ( 10 qaytar ) getDescription() ( "Sadə qəhvə" qaytar ) )

Qəhvəyə müxtəlif əlavələr əlavə etmək istəyirik, bunun üçün bəzi dekoratorlar yaradacağıq:

Class MilkCoffee ( constructor(coffee) ( this.coffee = coffee ) getCost() ( return this.coffee.getCost() + 2 ) getDescription() ( return this.coffee.getDescription() + ", milk" ) ) class WhipCoffee ( constructor(coffee) ( this.coffee = coffee ) getCost() ( return this.coffee.getCost() + 5 ) getDescription() ( return this.coffee.getDescription() + ", whip" ) ) class VanillaCoffee ( constructor (qəhvə) ( this.coffee = coffee ) getCost() ( return this.coffee.getCost() + 3 ) getDescription() ( qaytar this.coffee.getDescription() + ", vanil" ) )

İndi zövqünüzə görə qəhvə hazırlaya bilərsiniz:

Let someCoffee someCoffee = new SimpleCoffee() console.log(someCoffee.getCost())// 10 console.log(someCoffee.getDescription())// Simple Coffee someCoffee = new MilkCoffee(someCoffee) console.log(someCoffee.getCost(someCoffee.getCost) ))// 12 console.log(someCoffee.getDescription())// Sadə qəhvə, süd bir azQəhvə = yeni WhipCoffee(someCoffee) console.log(someCoffee.getCost())// 17 console.log(someCoffee.getDescription() )// Sadə qəhvə, süd, krem ​​bir azQəhvə = yeni VanillaQəhvə(birazQəhvə) console.log(someCoffee.getCost())// 20 console.log(someCoffee.getDescription())// Sadə qəhvə, süd, krem, vanil

Fasad

Kompüteri yandırmaq üçün sadəcə düyməni sıxmaq kifayətdir. Bu, çox sadədir, lakin açılan kompüterin içərisində çoxlu mürəkkəb şeylər baş verir. Mürəkkəb bir sistem üçün sadə interfeys Fasaddır.

İcra nümunəsi

Gəlin kompüter sinfi yaradaq:

Sinif Kompüteri ( getElectricShock() ( console.log("Ouch!") ) makeSound() ( console.log("Beep beep!") ) showLoadingScreen() ( console.log("Loading..") ) bam() ( console.log("İstifadəyə hazırdır!") ) closeEverything() ( console.log("Bup bup bup buzzzz!") ) sooth() ( console.log("Zzzzz") ) pullCurrent() ( konsol. log("Haaah!") ) )

və mürəkkəb funksiyaları üçün sadə Fasad:

Class ComputerFacade ( constructor(computer) ( this.computer = computer ) turnOn() ( this.computer.getElectricShock() this.computer.makeSound() this.computer.showLoadingScreen() this.computer.bam() ) turnOff() ( this.computer.closeEverything() this.computer.pullCurrent() this.computer.sooth() ) )

Bu, kompüterlə işləməyi xeyli asanlaşdırır:

Davamlı kompüter = yeni ComputerFacade(yeni Kompüter()) computer.turnOn() // Ah! Bip bip! Yüklənir.. İstifadəyə hazırdır! computer.turnOff() // Bup bup vızıltı! Haah! Zzzzz

Fürsətçi

Uzun məsafəli qatarlarda isti içkilər üçün su böyük qablarda qaynadılır - bir anda hamı üçün. Bu, elektrik enerjisinə (və ya qaza) qənaət etməyə imkan verir.

İş axtarış saytlarında sizi maraqlandıran iş seçimlərinə abunə ola bilərsiniz. Uyğun təklif görünəndə sayt sizə bildiriş göndərir.

Müşahidəçi nümunəsi baş vermiş dəyişikliklər haqqında bütün maraqlı obyektləri xəbərdar etməyə imkan verir.

İcra nümunəsi

Ərizəçilər bildirişlər almaq istəyirlər:

Const JobPost = title = (( title: title )) class JobSeeker ( constructor(name) ( this._name = name ) notify(jobPost) ( console.log(this._name, "yeni elandan xəbərdar edilib:", işPost.title) ) )

Və Bildiriş Şurası bu bildirişləri göndərə bilər:

Class JobBoard ( constructor() ( this._subscribers = ) subscribe(jobSeeker) ( this._subscribers.push(jobSeeker) ) addJob(jobPosting) ( this._subscribers.forEach(subscriber = ( subscriber.notify(jobPosting) )) ) )

// abunəçilər yarat const jonDoe = new JobSeeker("John Doe") const janeDoe = new JobSeeker("Jane Doe") const kaneDoe = new JobSeeker("Kane Doe") // mesaj lövhəsi yaradın // müraciət edənlər const jobBoard qeydiyyatdan keçin = new JobBoard() jobBoard.subscribe(jonDoe) jobBoard.subscribe(janeDoe) // yeni vakansiya barədə abunəçiləri xəbərdar edin jobBoard.addJob(JobPost("Proqram Mühəndisi")) // Con Doe yeni elan barədə məlumatlandırılıb: Proqram təminatı Mühəndis // Jane Doe yeni elan haqqında məlumat aldı: Proqram Mühəndisi

Ziyarətçi

Xaricə səyahət etmək üçün icazə (viza) almaq lazımdır. Ancaq ölkədə bir dəfə əlavə icazə istəmədən müxtəlif yerləri təhlükəsiz ziyarət edə bilərsiniz. Sadəcə onlar haqqında bilmək lazımdır.

Ziyarətçi nümunəsi mənbə kodunu dəyişmədən obyektlərə əlavə əməliyyatlar əlavə etməyə imkan verir.

İcra nümunəsi

Müxtəlif heyvan növləri ilə zooparkı simulyasiya edək:

Sinif Monkey ( shout() ( console.log("Ooh oo aa aa!") ) qəbul edin(əməliyyat) (operation.visitMonkey(this) ) sinif Aslan ( roar() ( console.log("Roaaar!") ) qəbul edin (əməliyyat) (operation.visitLion(this) ) ) class Dolphin ( speak() ( console.log("Tuut tuttu tuutt!") ) qəbul(əməliyyat) (operation.visitDolphin(this) ) )

İndi onların hansı səsləri çıxardığını dinləmək istəyirik. Bunun üçün Ziyarətçi yaradacağıq:

Davamlı danışın = ( visitMonkey(meymun)( monkey.shout() ), visitLion(lion)( lion.roar() ), visitDolphin(delphin)( delfin.danış() ) )

O, sadəcə olaraq hər sinfə daxil olur və istədiyiniz metodu çağırır:

Const monkey = new Monkey() const lion = new Lion() const delphin = new Dolphin() monkey.accept(speak) // Ooh oo aa aa! aslan.qəbul et(danış) // Roaaar! delphin.accept(danış) // Tuut tutt tuutt!

Ziyarətçi mövcud obyektlərin dəyişdirilməməsinə icazə verir. Onun köməyi ilə, məsələn, əlavə üsullar yaratmadan bütün bu heyvanlara tullanmaq imkanı əlavə edə bilərsiniz.

Davamlı tullanma = ( visitMonkey(meymun) ( console.log("20 fut hündürlükdən tullandı! ağaca!") ), visitLion(lion) ( console.log("7 fut tullandı! Yerə qayıt!") ) , visitDolphin(delphin) ( console.log("Su üzərində bir az getdi və gözdən itdi") ) )

Meymun.qəbul et(danış) // Ooh oo aa aa! monkey.accept(jump) // 20 fut hündürlükdən tullandı! ağaca! aslan.qəbul et(danış) // Roaaar! lion.accept(jump) // 7 fut tullandı! Yerə qayıt! delphin.accept(danış) // Tuut tutt tuutt! delfin.accept(jump) // Suyun üstündə bir az gəzib gözdən itdi

Strategiya

Bəzi məlumat dəstini təşkil etmək üçün siz qabarcıq çeşidləmə alqoritmindən istifadə edirsiniz. Kiçik həcmlərin öhdəsindən yaxşı gəlir, lakin böyük olanlarla yavaşlayır. Quicksort-un əks problemi var. Sonra dəstin ölçüsündən asılı olaraq alqoritmi dəyişməyə qərar verirsiniz. Bu sizin Strategiyanızdır.

Strategiya şablonu vəziyyətdən asılı olaraq istifadə olunan alqoritmi dəyişməyə imkan verir.

İcra nümunəsi

Birinci dərəcəli funksiyalar sizə Strategiyanı JavaScript-də həyata keçirməyə kömək edəcək.

Const bubbleSort = dataset => ( console.log("Bubble sort ilə çeşidləmə") // ... // ... verilənlər toplusunu qaytarmaq ) const quickSort = dataset => ( console.log("Tez çeşidləmə ilə çeşidləmə") / / ... // ... məlumat dəstini qaytarın)

Və bu, istənilən strategiyadan istifadə edə bilən müştəridir:

Const sorter = dataset => ( if(dataset.length > 5)( return quickSort ) else ( return bubbleSort ) )

İndi massivləri sıralaya bilərsiniz:

Const longDataSet = const shortDataSet = const sorter1 = sorter(longDataSet) const sorter2 = sorter(shortDataSet) sorter1(longDataSet) // Tez çeşidləmə sorter2(shortDataSet) // Bubble sort ilə çeşidləmə

dövlət

Siz Paint-də çəkirsiniz. Seçiminizdən asılı olaraq, fırça öz vəziyyətini dəyişir: qırmızı, mavi və ya hər hansı digər rəngə boyayır.

Dövlət nümunəsi vəziyyət dəyişdikdə sinfin davranışını dəyişməyə imkan verir.

İcra nümunəsi

Gəlin mətnin vəziyyətini dəyişə biləcəyiniz mətn redaktoru yaradaq - qalın, kursiv və s.

Bunlar çevrilmə funksiyalarıdır:

Const upperCase = inputString => inputString.toUpperCase() const smallCase = inputString => inputString.toLowerCase() const defaultTransform = inputString => inputString

Budur redaktorun özü:

Sinif TextEditor ( constructor(çevir) ( this._transform = transform ) setTransform(transform) ( this._transform = transform ) type(words) ( console.log(this._transform(words)) ) )

Siz işləyə bilərsiniz:

Const redaktoru = yeni TextEditor(defaultTransform) editor.type("Birinci sətir") editor.setTransform(böyük hərf) editor.type("İkinci sətir") editor.type("Üçüncü sətir") editor.setTransform(kiçik hərf) editor.type ("Dördüncü sətir") editor.type("Beşinci sətir") // Birinci sətir // İKİNCİ SƏTİR // ÜÇÜNCÜ SƏTİR // dördüncü sətir // beşinci sətir

Şablon metodu

Müəyyən bir plana uyğun olaraq bir ev tikirsiniz: əvvəlcə təməl, sonra divarlar və yalnız sonra dam. Bu addımların sırası dəyişdirilə bilməz, lakin onların icrası fərqli ola bilər.

Şablon metodu alqoritmin "skeletini" müəyyən edir, lakin addımların həyata keçirilməsini uşaq siniflərinə həvalə edir.

İcra nümunəsi

Tətbiqi sınaqdan keçirmək, qurmaq və yerləşdirmək üçün alət yaradaq.

Əsas sinif montaj alqoritminin skeletini müəyyən edir:

Sinif Qurucusu ( // Şablon metodu build() ( this.test() this.lint() this.assemble() this.deploy() ) )

Və uşaq sinifləri hər bir addımın xüsusi həyata keçirilməsidir:

AndroidBuilder sinfi Builder-i genişləndirir ( test() ( console.log("Android testləri işləyir") ) lint() ( console.log("Android kodunun bağlanması") ) assemble() ( console.log("Android quruluşunun yığılması" ) ) deploy() ( console.log("Android quruluşunu serverə yerləşdirir") ) ) sinif IosBuilder Builder-i genişləndirir ( test() ( console.log("ios testləri işləyir") ) lint() ( console.log("Linting ios kodu") ) assemble() ( console.log("ios quruluşunun yığılması") ) deploy() ( console.log("ios quruluşunun serverdə yerləşdirilməsi") ) )

Layihəni toplayaq:

Const androidBuilder = new AndroidBuilder() androidBuilder.build() // Android testləri həyata keçirilir // Android kodunun yığılması // Android quruluşunun yığılması // Android quruluşunun serverə yerləşdirilməsi const iosBuilder = new IosBuilder() iosBuilder.build() // ios testlərinin icrası // ios kodunun rənglənməsi // ios quruluşunun yığılması // ios quruluşunun serverə yerləşdirilməsi

  • Tərcümə

Tərcüməçinin qeydi: JavaScript-də varislik mövzusu yeni başlayanlar üçün ən çətin mövzulardan biridir. Klass açar sözü ilə yeni sintaksisin əlavə edilməsi ilə mirası başa düşmək asan olmadı, baxmayaraq ki, köklü yeni bir şey ortaya çıxmadı. Bu məqalə JavaScript-də prototip varisliyinin həyata keçirilməsinin nüanslarına toxunmur, buna görə də oxucunun hər hansı bir sualı varsa, aşağıdakı məqalələri oxumağı məsləhət görürəm: JavaScript haqqında əsaslar və yanlış təsəvvürlər və JavaScript-də OOP-u başa düşmək [1-ci hissə]

Tərcümə ilə bağlı hər hansı şərh üçün şəxsi mesaj vasitəsilə bizimlə əlaqə saxlayın.

JavaScript çox güclü bir dildir. O qədər güclüdür ki, onun daxilində obyektlərin dizaynı və yaradılmasının bir çox müxtəlif yolları mövcuddur. Hər bir metodun öz müsbət və mənfi cəhətləri var və mən yeni başlayanlara bunu anlamağa kömək etmək istərdim. Bu, mənim əvvəlki yazımın davamıdır, JavaScript-i “kateqoriyalara ayırmağı dayandırın”. Mən çoxlu suallar və misal tələb edən şərhlər aldım və məhz bu məqsədlə bu məqaləni yazmağa qərar verdim.

JavaScript prototip mirasdan istifadə edir Bu o deməkdir ki, JavaScript-də obyektlər digər obyektlərdən miras alınır. () əyri mötərizələrdən istifadə etməklə yaradılmış JavaScript-də sadə obyektlərin yalnız bir prototipi var: Obyekt.prototip. Obyekt.prototip, öz növbəsində, həm də obyekt və bütün xassələri və üsullarıdır Obyekt.prototip bütün obyektlər üçün mövcuddur.

Kvadrat mötərizədə yaradılan massivlər də daxil olmaqla bir neçə prototipə malikdir Obyekt.prototipmassiv.prototip. Bu o deməkdir ki, bütün xüsusiyyətlər və üsullar Obyekt.prototipmassiv.prototip bütün massivlər üçün mövcuddur. Eyni adlı xüsusiyyətlər və üsullar, məsələn .valueOf.ToString, ən yaxın prototipdən, bu halda -dən çağırılır massiv.prototip.

Prototip Tərifləri və Obyekt Yaratma Metod 1: Konstruktor Nümunəsi JavaScript-in konstruktorlar adlı xüsusi funksiya növü var və onlar digər dillərdəki konstruktorlarla eyni şəkildə fəaliyyət göstərirlər. Konstruktor funksiyaları yalnız açar sözdən istifadə etməklə çağırılır yeni və yaradılmış obyekti açar söz vasitəsilə konstruktor funksiyasının konteksti ilə əlaqələndirin bu. Tipik bir konstruktor bu kimi görünə bilər:
funksiya Animal(type)( this.type = type; ) Animal.isAnimal = function(obj, type)( if(!Animal.prototype.isPrototypeOf(obj))( return false; ) return type ? obj.type === növü: doğru; ); function Dog(ad, cins)( Animal.call(bu, "it"); this.name = name; this.cins = cins; ) Object.setPrototypeOf(Dog.prototype, Animal.prototype); Dog.prototype.bark = function())( console.log("ruff, ruff"); ); Dog.prototype.print = function())( console.log("The It " + this.name + " is a " + this.cins); ); ); Dog.isDog = function(obj)( return Animal.isAnimal(obj, "it"); );
Bu konstruktordan istifadə digər dillərdə obyekt yaratmaqla eyni görünür:
var sparkie = new Dog("Sparkie", "Border Collie"); sparkie.name; // "Sparkie" sparkie.cins; // "Border Collie" sparkie.bark(); // konsol: "ruff, ruff" sparkie.print(); // konsol: "Köpək Sparkie Border Colliedir" Dog.isDog(sparkie); // doğru
qabıqçap edin konstruktordan istifadə etməklə yaradılmış bütün obyektlərə tətbiq olunan prototip üsulları it. Xüsusiyyətlər adcins konstruktorda işə salınır. Prototipdə müəyyən ediləcək bütün metodlar və konstruktor tərəfindən işə salınacaq xassələr üçün ümumi təcrübədir.Metod 2: ES2015 (ES6) Açar sözündə Sinfin müəyyən edilməsi sinifəvvəldən JavaScript-də qorunub saxlanılıb və indi nəhayət ondan istifadə etmək vaxtıdır. JavaScript-də sinif tərifləri digər dillərə bənzəyir.
sinif Heyvan ( constructor(növ)( this.type = type; ) static isAnimal(obj, type)( if(!Animal.prototype.isPrototypeOf(obj))( return false; ) return type ? obj.type === type : true; ) ) sinif İt genişləndirir Animal ( constructor(name, cins)( super("dog"); this.name = name; this.breed = cins; ) bark())( console.log("ruff, ruff" " ); ) print())( console.log("The it " + this.name + " is a " + this.cins); ) static isDog(obj)( return Animal.isAnimal(obj, "dog") ;))
Bir çox insanlar bu sintaksisi əlverişli hesab edirlər, çünki o, bir blokda statik və prototip metodların konstruktoru və bəyannaməsini birləşdirir. İstifadəsi əvvəlki üsulla tamamilə eynidır.
var sparkie = new Dog("Sparkie", "Border Collie"); Metod 3: Açıq Prototip Bəyanatı, Object.create, Fabrika Metod Bu üsul yeni açar söz sintaksisinin əslində nə olduğunu göstərir sinif prototip mirasdan istifadə edir. Bu üsul həm də operatordan istifadə etmədən yeni obyekt yaratmağa imkan verir yeni.
var Animal = ( yarat(növ)( var heyvan = Obyekt.yarat(Heyvan.prototip); heyvan.tip = növü; heyvanı qaytar; ), isAnimal(obj, tip)( if(!Animal.prototip.isPrototipOf(obj)) )( false qaytarın; ) qaytarma növü ? obj.type === növü: doğru; ), prototip: () ); var İt = ( yarat(ad, cins)( var proto = Object.assign(Animal.create("it"), Dog.prototype); var it = Object.create(proto); it.name = ad; it. cins = cins; qaytar it; ), isDog(obj)( return Animal.isAnimal(obj, "it"); ), prototip: ( bark())( console.log("ruff, ruff"); ), çap edin ( )( console.log("The It " + this.name + " is a " + this.cins); ) ) );
Bu sintaksis rahatdır, çünki prototip açıq şəkildə elan edilmişdir. Prototipdə nəyin müəyyən edildiyi və obyektin özündə nəyin müəyyən edildiyi aydındır. Metod Obyekt.yarat rahatdır, çünki müəyyən edilmiş prototipdən obyekt yaratmağa imkan verir. ilə yoxlanılır .isPrototypeOf hələ də hər iki halda işləyir. İstifadələr müxtəlifdir, lakin həddindən artıq deyil:
var sparkie = Dog.create("Sparkie", "Border Collie"); sparkie.name; // "Sparkie" sparkie.cins; // "Border Collie" sparkie.bark(); // konsol: "ruff, ruff" sparkie.print(); // konsol: "Köpək Sparkie Border Colliedir" Dog.isDog(sparkie); // true Metod 4: Object.create, yüksək səviyyəli zavod, təxirə salınmış prototip Bu üsul, sinfin zavod metodu ilə obyekt olduğu halda, sinifin özü zavod olduğu halda, 3-cü metodun cüzi modifikasiyasıdır. . Konstruktor nümunəsinə bənzər (metod 1), lakin zavod metodundan istifadə edir və Obyekt.yarat.
funksiyası Animal(type)( var heyvan = Object.create(Animal.prototype); animal.type = type; return animal; ) Animal.isAnimal = function(obj, type)( if(!Animal.prototype.isPrototypeOf(obj)) )( false qaytarın; ) qaytarma növü ? obj.type === növü: doğru; ); Animal.prototype = (); funksiyası İt(ad, cins)( var proto = Object.assign(Animal("it"), Dog.prototype); var it = Object.create(proto); it.name = ad; it.cins = cins; qaytarmaq it; ) Dog.isDog = function(obj)( return Animal.isAnimal(obj, "it"); ); Dog.prototype = ( qabıq())( console.log("ruff, ruff"); ), print())( console.log("İt " + this.name + " " + this.cinsdir) ;)))
Bu üsul maraqlıdır, çünki birinci üsula bənzəyir, lakin açar söz tələb etmir yeni və operatorla işləyir instanceOf. İstifadə birinci üsulla eynidir, lakin açar sözdən istifadə etmədən yeni:
var sparkie = Dog("Sparkie", "Border Collie"); sparkie.name; // "Sparkie" sparkie.cins; // "Border Collie" sparkie.bark(); // konsol: "ruff, ruff" sparkie.print(); // konsol: "Köpək Sparkie Border Colliedir" Dog.isDog(sparkie); // doğru Müqayisə Metod 1 vs Metod 4 Metod 4 əvəzinə Metod 1-dən istifadə etmək üçün çox az səbəb var. Metod 1 ya açar sözdən istifadə etməyi tələb edir. yeni, və ya konstruktorda aşağıdakı çeki əlavə edin:
if(!(bu Foo nümunəsi))( yeni Foo qaytarın(a, b, c); )
Bu vəziyyətdə istifadə etmək daha asandır Obyekt.yarat zavod üsulu ilə. Siz həmçinin funksiyalardan istifadə edə bilməzsiniz Funksiya #zəng və ya Funksiya#tətbiq edin konstruktor funksiyaları ilə, çünki onlar açar söz kontekstini üstələyir bu. Yuxarıdakı yoxlama bu problemi həll edə bilər, lakin əvvəlcədən naməlum sayda arqumentlərlə işləmək lazımdırsa, zavod metodundan istifadə etməlisiniz Metod 2 vs Metod 3 Konstruktorlar və operator haqqında eyni mülahizə yeni yuxarıda qeyd olunanlar bu halda tətbiq edilir. ilə yoxlanılır misal yeni sintaksis istifadə edildikdə tələb olunur sinif operatordan istifadə etmədən yeni və ya istifadə olunur Funksiya #zəng və ya Funksiya#tətbiq edin.Fikrimcə, proqramçı öz kodunda aydınlığa çalışmalıdır. Metod 3 sintaksisi əslində nə baş verdiyini çox aydın göstərir. O, həmçinin çoxlu miras və yığın miraslarından istifadəni asanlaşdırır. Operatordan bəri yeni ilə uyğun gəlmədiyi üçün açıq/qapalı prinsipi pozur müraciət edin və ya zəng edin, bunun qarşısını almaq lazımdır. Açar söz sinif JavaScript-də mirasın prototip xarakterini sinif sisteminin maskası arxasında gizlədir.
“Sadə, mürəkkəbdən yaxşıdır” və daha “mürəkkəb” hesab edildiyi üçün dərslərdən istifadə sadəcə lazımsız, texniki baş ağrısıdır.
İstifadəsi Obyekt.yarat copula istifadə etməkdən daha ifadəli və aydındır yenibu. Bundan əlavə, prototip fabrikin özündən kənarda ola bilən obyektdə saxlanılır və beləliklə, metodlar əlavə etməklə daha asan dəyişdirilə və genişləndirilə bilər. Eynilə ES6-dakı dərslər kimi.
Açar söz sinif, JavaScript-in ən zərərli xüsusiyyəti ola bilər. Standartın yazılması prosesində iştirak edən parlaq və çox çalışqan insanlara böyük hörmətim var, lakin hətta parlaq insanlar bəzən yanlış hərəkətlər edirlər. - Erik Elliott
Dilin təbiətinə zidd olaraq lazımsız və bəlkə də zərərli bir şey əlavə etmək düşüncəsiz və səhvdir.
İstifadə etmək qərarına gəlsəniz sinif, Ümid edirəm ki, kodunuzla heç vaxt işləməyəcəyəm. Məncə, tərtibatçılar konstruktorlardan istifadə etməkdən çəkinməlidirlər, sinifyeni, və dilin paradiqmasına və arxitekturasına daha təbii olan üsullardan istifadə edin. Lüğət Obyekt.təyin(a, b) obyektin bütün sadalanan xassələrini kopyalayır b etiraz etmək a və sonra obyekti qaytarır a
Object.create(proto) göstərilən prototipdən yeni obyekt yaradır proto
Object.setPrototypeOf(obj, proto) daxili mülkiyyəti dəyişir [] obyekt obj haqqında proto

Teqlər: Teqlər əlavə edin

WordPress hər yerdə şablonlardan istifadə edir və Javascript də istisna deyil. Bu yazıda biz WordPress-də JS-də istifadə oluna bilən HTML şablonları yaratmaq bacarığından danışacağıq. Bu şablonları yaratmaq və istifadə etmək çox asandır, WordPress-də bir çox başqa şeylər kimi.

Javascript-də şablon yaratmağın bir çox yolu var, hətta onlar üçün Bığ adlı ayrıca spesifikasiya da var. Javascript də daxil olmaqla bir çox dillərdə həyata keçirilir. Məsələn, Handlebars kitabxanası bu spesifikasiyadan istifadə edir və hətta onu bir az da genişləndirir. Və ya məşhur Underscore mini-kitabxanası.

3.5 versiyasından bəri WordPress-in əsas hissəsində JS üçün rahat şablon mühərriki var. Məsələn, media yükləyicisi üçün bloklar yaratarkən admin panelində istifadə olunur. Yuxarıda qeyd olunan Alt Çizgi kitabxanasına əsaslanaraq, sintaksis Bığ spesifikasiyasına daha uyğun olması üçün bir qədər dəyişdirilib.

WordPress-də şablon yaratmaq üçün wp.template metodu var

wp.template(id)

HTML kodundan şablon obyekti yaradır. JS-də istifadə üçün hazır HTML kodu əldə etmək üçün şablonu yaradılmış obyektə doldurmaq üçün məlumatları ötürməlisiniz.

Qaytarır

Funksiya. Şablon interpolasiyası üçün məlumatları ötürmək funksiyası.

var şablonundan istifadə = wp.template(id); var HTML = şablon(məlumat); id (xətt)

Şablonun HTML kodunu ehtiva edən HTML elementinin ID-si. HTML elementi burada tmpl- prefiksi ilə müəyyən edilmiş id atributuna malik olmalıdır.

Məsələn, əgər burada foo təyin etsəniz, HTML elementində id id="tmpl-foo" olmalıdır.

Data (bir obyekt)Şablonu doldurmaq üçün istifadə ediləcək JS məlumat obyekti. Məsələn: (mətn: "Salam") .

Nümunə Doldurma (İnterpolyasiya)
  • (((data.unescaped))) - təmizlənməmiş məlumatlar.
  • ((data.escaped)) - təmizlənmiş məlumatlar.
  • - js prosesi (qiymətləndirmə).
Məlumat prefiksi.

şablondakı məlumatlar mənbə məlumat obyektidir. Şablonda məlumat açarından istifadə etməlisiniz.

wp_send_json_success() və wp_send_json_error() funksiyaları tərəfindən qaytarılan məlumat strukturuna uyğun gəlmək üçün wp.template bütün qəbul edilmiş məlumatları data dəyişəninə yığır. Buna görə şablondakı hər bir parametrdən əvvəl məlumatları göstərməlisiniz. , əks halda xəta alacağıq: (xüsusiyyət) müəyyən edilməyib.

Düzgün (((data.name)))

Yanlış (((ad)))

Nümunə şablon

Sadəcə olaraq çıxış olacaq.

Gəlin escapedValue ((data.escapedValue)) dəyişəninin dəyərini göstərək.

Məlumatda işarələmə varsa, onu qaçırmadan çap edin:

(((data.unescapedValue)))

Bəzi məntiq yerinə yetirmək lazım olanda.

Yalnız data.trueValue = true olduqda çap olunacaq.

Şablon yaratmaq və yaratmaq Şablon yaratmaq

Şablonun DOM ağacında heç bir şəkildə görünməməsini təmin etmək üçün onu type="text/html" tipli skript etiketində yaratmaq adətdir.

Salam (((data.name)))

İd atributu tmpl- ilə başlamalıdır, bu prefiksdən sonra hər şey wp.template("my-şablon") funksiyasında istifadə olunacaq.

Skript teqində şablon yaratmaq, brauzer tərəfindən heç bir şəkildə istifadə edilməyən html elementi yaratmaq üçün əla bir hackdir. Brauzer üçün anlaşılmaz tip göstərildikdə, o, sadəcə olaraq bizə lazım olan html teqinə məhəl qoymur.

Şablon hər hansı digər HTML elementində də yaradıla bilər (məsələn, içərisində, sonra gizlənə bilər), sizə lazım olan yeganə şey id atributunu təyin etməkdir.

Şablon yaratmaq üçün xüsusi HTML teqi də var, lakin IE-də o, dəstəklənmir. Amma ümumilikdə bu olduqca aktualdır.

Şablon yaratmaq

wp.template() funksiyanı qaytarır, ona görə də nəticəni html elementinə ötürməyə və ya nəticəni konsola çap etməyə çalışmayın. Tipik olaraq, wp.template() nəticəsi dəyişənə ötürülür və sonra həmin dəyişən funksiya kimi istifadə olunur və şablonun doldurulmalı olduğu verilənlər ötürülür.

Nümunə (şablon yuxarıda göstərilmişdir)

// JS var şablonu = wp.template("mənim şablonum"), data = (ad: "Victor" ); jQuery(".mənim elementim").html(şablon(məlumat));

Nəticədə HTML-də əldə edirik:

Salam Viktor

Şablondan istifadə edərək AJAX şərhinin nümunəsi

Şablon yaradın və skripti mövzunun functions.php faylına daxil edin:

  • (((data.gravatar))) ((data.comment_author))