If you're seeing this message, it means we're having trouble loading external resources on our website.

Եթե գտնվում ես վեբ զտիչի հետևում, խնդրում ենք համոզվել, որ *.kastatic.org և *.kasandbox.org տիրույթները հանված են արգելափակումից։

Հիմնական նյութ

Կոճակ օբյեկտ

Լավագույն եղանակը՝ ստեղծելու այնպիսի հզոր կոդ, որը հնարավոր կլինի օգտագործել մեկից ավելի անգամներ, օբյեկտային կողմնորոշվածություն ունեցող ծրագրավորումն օգտագործելն է, մանավանդ, երբ խոսքն այնպիսի UI control վերահսկիչներ ստեղծելու մասին է, ինչպիսիք են կոճակները: Օբյեկտային կողմնորոշվածություն ունեցող ծրագրավորման մեջ դիտարկում ենք մեր ծրագրային աշխարհը այնպիսի վերացական առարկաների տեսակների տեսանկյունից, որոնք ունեն հստակ վարքագիծ, այնուհետև ստեղծում ենք այդ առարկաների տեսակների հստակ ակնթարթներ՝ որոշակի պարամետրերով: Եթե մոռացել ես՝ ինչպես պետք է դա անել JavaScript-ում, կարող ես վերհիշել այստեղ:
Որպեսզի կոճակներ ստեղծելու համար կարողանանք օգտագործել OOP-ն, մենք պետք է սահմանենք Կոճակ առարկայի տեսակը, այնուհետև դրա համար սահմանենք մեթոդներ, օրինակ՝ այն նկարելու և մկնիկը կառավարելու համար: Մենք ուզում ենք այնպիսի կոդ գրել, որը կունենա հետևյալ տեսքը.
var btn1 = new Button(...);
btn1.draw();

mouseClicked = function() {
  if (btn1.isMouseInside()) {
     println("Whoah, you clicked me!");
  }
}
Արի հակադրենք այն վերջին հոդվածի ժամանակ մեր գրած կոդին.
var btn1 = {...};
drawButton(btn1);

mouseClicked = function() {
  if (isMouseInside(btn1)) {
     println("Whoah, you clicked me!");
  }
}
Դրանք բավական նման են, այնպես չէ՞: Սակայն նրանց միջև կա մի մեծ տարբերություն. բոլոր ֆունկցիաները սահմանված են Կոճակ առարկայի տեսակի վրա. իրականում դրանք պատկանում են կոճակներին: Հատկությունների և վարքագծի միջև զուգակցումն ավելի ամուր է, և դրա արդյունքում հիմնականում ստացվում է ավելի պարզ և մեկից ավելի անգամ օգտագործման կոդ:
Կոճակի առարկայի տեսակը սահմանելու համար մենք պետք է սկսենք կոնստրուկտորից՝ այն հատուկ ֆունկցիայից, որը վերցնում է կոնֆիգուրացիայի պարամետրերը և սկիզբ է դնում առարկայի ակնթարթի նախնական հատկություններին:
Փորձնական. ահա կոնստրուկտոր, որը հաշվի է առնում x, y լայնությունը և բարձրությունը.
var Button = function(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
};

var btn1 = new Button(100, 100, 150, 150);
Դա, անշուշտ, աշխատում է, սակայն ուզում եմ մեկ այլ տարբերակ առաջարկել: Պարամետրերն առանձին-առաձին դիտարկելու փոխարեն կոնստրուկտորը կարող է դիտարկել օբյեկտի կոնֆիգուրացիան:
var Button = function(config) {
    this.x = config.x;
    this.y = config.y;
    this.width = config.width;
    this.height = config.height;
    this.label = config.label;
};
Config օբյեկտի առավելությունն այն է, որ մենք կարող ենք անընդհատ նոր պարամետրեր ավելացնել (օրինակ՝ label) կոնստրուկտորի համար, և հեշտ կլինի հասկանալ, թե ինչ է անում պարամետրերից յուրաքանչյուրը, երբ ստեղծում ենք կոճակը:
var btn1 = new Button({
    x: 100, y: 100,
    width: 150, height: 50,
    label: "Please click!"});
Բայց մենք կարող ենք մի քայլ էլ առաջ գնալ դրանից: Ի՞նչ կլինի, եթե կոճակների մեծամասնությունը ունենան միևնույն լայնությունն ու բարձրությունը: Մենք ստիպված չենք լինի ամեն անգամ հստակեցնել լայնության ու բարձրության պարամետրերը յուրաքանչյուր կոճակի համար. դա կարվի միայն անհրաժեշտության դեպքում: Կարող ենք այնպես անել, որ կոնստրուկտորը ստուգի՝ արդյոք հատկությունը սահմանված է config օբյեկտի մեջ, և եթե ոչ, ապա տանք դրան սկզբնական արժեք:
var Button = function(config) {
    this.x = config.x || 0;
    this.y = config.y || 0;
    this.width = config.width || 150;
    this.height = config.height || 50;
    this.label = config.label || "Click";
};
Այժմ կարող ենք կանչել այն՝ օգտագործելով միայն հատկությունների ենթաբազմություն, քանի որ մյուս հատկություններին արդեն իսկ տրված կլինեն սկզբնական արժեքներ:
var btn1 = new Button({x: 100, y: 100, label: "Please click!"});
Եվ այս ամենը՝ ընդամենը մեկ կոնստրուկտորի համա՞ր: Բայց խոստանում եմ, արդյունքը արդարեցված կլինի:
Այժմ, երբ կոնստրուկտորն արդեն ուղղված է, արի սահմանենք որոշակի վարքագիծ. draw (նկարելու) մեթոդը: Դա կլինի այն նույն կոդը, ինչ որ drawButton ֆունկցիան, բայց այն this-ից կվերցնի բոլոր հատկությունները, քանի որ այն սահմանված է հենց օբյեկտի նախատիպի վրա:
Button.prototype.draw = function() {
    fill(0, 234, 255);
    rect(this.x, this.y, this.width, this.height, 5);
    fill(0, 0, 0);
    textSize(19);
    textAlign(LEFT, TOP);
    text(this.label, this.x+10, this.y+this.height/4);
};
Երբ այն արդեն սահմանված է, կարող ենք կանչել այսպես՝
btn1.draw();
Ահա մի ծրագիր, որն օգտագործում է այդ կոճակ օբյեկտը 2 կոճակ ստեղծելու համար. ուշադրություն դարձրու, թե ինչ հեշտ է ստեղծել և նկարել մի քանի կոճակ.
Մենք, սակայն, բաց ենք թողել ամենադժվար մասը, թե ինչպես կառավարել մկնիկի սեղմելու գործընթացը: Կարելի է սկսել կոճակի՝ Button-ի նախատիպի վրա այնպիսի ֆունկցիա սահմանելով, որը կաշխատի, եթե օգտատերը սեղմի կոնկրետ կոճակի սահմանների ներսում: Կրկին հիշենք, որ սա նման է այն ֆունկցիային, որն ունեինք նախկինում, բայց այժմ այն վերցնում է բոլոր հատկությունները this-ից և ոչ թե փոխանցված օբյեկտից:
Button.prototype.isMouseInside = function() {
    return mouseX > this.x &&
           mouseX < (this.x + this.width) &&
           mouseY > this.y &&
           mouseY < (this.y + this.height);
};
Այժմ կարող ենք օգտագործել այն mouseClicked ֆունկցիայի ներսից:
mouseClicked = function() {
    if (btn1.isMouseInside()) {
        println("You made the right choice!");
    } else if (btn2.isMouseInside()) {
        println("Yay, you picked me!");
    }
};
Փորձարկիր այն ներքևում. սեղմիր կոճակներից յուրաքանչյուրը:
Բայց մի բան կա, որն ինձ դուր չի գալիս. այն է՝ թե ինչպես ենք մենք կարգավորել մկնիկի սեղմելը: Օբյեկտային կողմնորոշվածություն ունեցող ծրագրավորման ողջ իմաստն այն է, որ հավաքենք առարկային վերաբերող բոլոր վարքագծերը առարկայի ներսում և օգտագործենք հատկությունները վարքագիծն անհատականցնելու համար: Սակայն մենք թողել ենք որոշ վարքագծեր առարկայից դուրս, println-ները՝ mouseClicked-ի ներսում.
mouseClicked = function() {
    if (btn1.isMouseInside()) {
        println("You made the right choice!");
    } else if (btn2.isMouseInside()) {
        println("Yay, you picked me!");
    }
};
Այդ print պնդումները պետք է ինչ-որ կերպ ավելի լավ կապված լինեն կոճակին, ինչպես, օրինակ՝ մի բան, որը փոխանցում ենք կոնստրուկտորին: Ելնելով դրա ներկայիս տեսքից՝ մենք կարող ենք որոշել հաղորդագրությունը փոխանցել կոնստրուկտորի config-ի մեջ և սահմանել, որ handleMouseClick ֆունկցիան այն տպի:
var Button = function(config) {
    ...
    this.message = config.message || "Clicked!";
};

Button.prototype.handleMouseClick = function() {
    if (this.isMouseInside()) {
         println(this.message);
    }
};

var btn1 = new Button({
    x: 100,
    y: 100,
    label: "Please click!",
    message: "You made the right choice!"
});

mouseClicked = function() {
   btn1.handleMouseClick();
};
Այսպես շատ ավելի լավ է, քանի որ այժմ այն ամենը, ինչ կապ ունի յուրաքանչյուր կոճակի որոշակի վարքագծի հետ, գտնվում է կոնստրուկտորում: Բայց դա նաև չափից շատ պարզ է: Իսկ ի՞նչ կլինի, եթե ցանկանանք, հաղորդագրություն տպելուց բացի, ուրիշ գործողություններ կատարել, օրինակ՝ մի քանի պատկեր նկարել կամ տեսարաններ փոխել. ինչ-որ բան, որը կպահանջի մի քանի տողանոց կոդ: Այդ դեպքում մեզ հարկավոր կլինի կոնստրուկտորին ապահովել ոչ միայն տողայինով, դրան հարկավոր է տալ մի շարք կոդեր: Ինչպե՞ս կարող ենք դա անել:
... Ֆունկցիայի միջոցով: JavaScript-ում (բայց ոչ բոլոր լեզուներում) կարող ենք փոխանցել ֆունկցիաները՝ որպես ֆունկցիաների պարամետրեր: Դա օգտակար է մի շարք դեպքերում, սակայն մասնավորապես այն օգտակար է այն ժամանակ, երբ սահմանում ենք վարքագիծ այնպիսի UI վերահսկիչների համար, ինչպիսիք են կոճակները: Մենք կարող ենք ասել ֆունկցիային. «Ահա այս ֆունկցիան: Սրանք մի շարք կոդեր են, որոնք դու պետք է կանչես այն ժամանակ, երբ օգտատերը սեղմում է կոճակը»: Դրանք կոչվում են «callback» ֆունկցիաներ, քանի որ դրանք միանգամից չեն կանչվում, այլ հետ են կանչվում ավելի հարմար ժամանակ:
Կարող ենք սկսել՝ ֆունկցիա հանդիսացողonClick-ին պարամետր փոխանցելով:
var btn1 = new Button({
    x: 100,
    y: 100,
    label: "Please click!",
    onClick: function() {
       text("You made the right choice!", 100, 300);
    }
});
Այնուհետև պետք է համոզվենք, որ կոնստրուկտորն օգտագործում է onClick հատկությունը՝ փոխանցվածին համապատասխան: Նախնականի համար, եթե չկա փոխանցված onClick, մենք ուղղակի կստեղծենք «no-op» ֆունկցիա, որն ընդհանրապես «ոչ մի գործողություն» չի կատարում: Այն գոյություն ունի միայն այն բանի համար, որ մենք կարողանանք այն կանչել և չբախվել ինչ-որ սխալի:
var Button = function(config) {
    // ...
    this.onClick = config.onClick || function() {};
};
Վերջում պետք է հետ կանչենք հետկանչի ֆունկցիան այն ժամանակ, երբ օգտատերը սեղմում է կոճակը: Իրականում դա շատ հեշտ է, կարելի է դա անել՝ ուղղակի կանչելով այն հատկության անունը, որի մեջ այն պահպանել ենք, և դրանից հետո դնելով դատարկ փակագծեր:
Button.prototype.handleMouseClick = function() {
    if (this.isMouseInside()) {
        this.onClick();
    }
};
Ահա և վերջ: Մենք ունենք Կոճակ օբյեկտ, որից հեշտությամբ կարող ենք ստեղծել նոր կոճակներ՝ այնպես անելով, որ յուրաքանչյուր կոճակ տարբեր տեսք ունենա և տարբեր կերպ արձագանքի մկնիկի սեղմելուն: Փորձարկիր դա ներքևի օրինակի վրա և տես, թե ինչ է կատարվում, երբ փոխում ես կոճակի պարամետրերը:
Այժմ, երբ ունես դա՝ որպես կաղապար, կարող ես այլ կերպ անհատականցնել քո կոճակները, օրինակ՝ տարբեր գույներով, կամ այնպես անես, որ դրանք արձագանքեն տարբեր գործողություններին, ինչպես, օրինակ՝ mouseover-ի դեպքում: Փորձարկիր դա քո ծրագրերում:

Ուզո՞ւմ ես միանալ խոսակցությանը։

Առայժմ հրապարակումներ չկան։
Անգլերեն հասկանո՞ւմ ես: Սեղմիր այստեղ և ավելի շատ քննարկումներ կգտնես «Քան» ակադեմիայի անգլերեն կայքում: