ÐамÑкание â ÑÑо комбинаÑÐ¸Ñ ÑÑнкÑии и лекÑиÑеÑкого окÑÑжениÑ, в коÑоÑом ÑÑа ÑÑнкÑÐ¸Ñ Ð±Ñла опÑеделена. ÐÑÑгими Ñловами, замÑкание даÑÑ Ð²Ð°Ð¼ доÑÑÑп к Scope внеÑней ÑÑнкÑии из внÑÑÑенней ÑÑнкÑии. Ð JavaScript замÑÐºÐ°Ð½Ð¸Ñ ÑоздаÑÑÑÑ ÐºÐ°Ð¶Ð´Ñй Ñаз пÑи Ñоздании ÑÑнкÑии, во вÑÐµÐ¼Ñ ÐµÑ ÑозданиÑ.
ÐекÑиÑеÑÐºÐ°Ñ Ð¾Ð±Ð»Ð°ÑÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑиРаÑÑмоÑÑим ÑледÑÑÑий пÑимеÑ:
function init() {
var name = "Mozilla"; // name - локалÑÐ½Ð°Ñ Ð¿ÐµÑеменнаÑ, ÑÐ¾Ð·Ð´Ð°Ð½Ð½Ð°Ñ Ð² init
function displayName() {
// displayName() - внÑÑÑеннÑÑ ÑÑнкÑиÑ, замÑкание
alert(name); // displayName() иÑполÑзÑÐµÑ Ð¿ÐµÑеменнÑÑ, обÑÑвленнÑÑ Ð² ÑодиÑелÑÑкой ÑÑнкÑии
}
displayName();
}
init();
init()
ÑоздаÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑÑ Ð¿ÐµÑеменнÑÑ name
и опÑеделÑÐµÑ ÑÑнкÑÐ¸Ñ displayName()
. displayName()
â ÑÑо внÑÑÑеннÑÑ ÑÑнкÑÐ¸Ñ â она опÑеделена внÑÑÑи init()
и доÑÑÑпна ÑолÑко внÑÑÑи Ñела ÑÑнкÑии init()
. ÐбÑаÑиÑе внимание, ÑÑо ÑÑнкÑÐ¸Ñ displayName()
не Ð¸Ð¼ÐµÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ñ
ÑобÑÑвеннÑÑ
локалÑнÑÑ
пеÑеменнÑÑ
. Ðднако, поÑколÑÐºÑ Ð²Ð½ÑÑÑенние ÑÑнкÑии имеÑÑ Ð´Ð¾ÑÑÑп к пеÑеменнÑм внеÑниÑ
ÑÑнкÑий, displayName()
Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð´Ð¾ÑÑÑп к пеÑеменной name
, обÑÑвленной в ÑодиÑелÑÑкой ÑÑнкÑии init()
.
ÐÑполниÑе ÑÑÐ¾Ñ ÐºÐ¾Ð´ и обÑаÑиÑе внимание, ÑÑо команда alert()
внÑÑÑи displayName()
благополÑÑно вÑÐ²Ð¾Ð´Ð¸Ñ Ð½Ð° ÑкÑан ÑодеÑжимое пеÑеменной name
обÑÑвленной в ÑодиÑелÑÑкой ÑÑнкÑии. ÐÑо пÑÐ¸Ð¼ÐµÑ Ñак назÑваемой лекÑиÑеÑкой облаÑÑи видимоÑÑи (lexical scoping): в JavaScript облаÑÑÑ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ Ð¿ÐµÑеменной опÑеделÑеÑÑÑ Ð¿Ð¾ ÐµÑ ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² коде (ÑÑо оÑевидно лекÑиÑеÑки), и вложеннÑе ÑÑнкÑии имеÑÑ Ð´Ð¾ÑÑÑп к пеÑеменнÑм, обÑÑвленнÑм вовне. ÐÑÐ¾Ñ Ð¼ÐµÑ
анизм и назÑваеÑÑÑ Lexical scoping (облаÑÑÑ Ð´ÐµÐ¹ÑÑвиÑ, огÑаниÑÐµÐ½Ð½Ð°Ñ Ð»ÐµÐºÑиÑеÑки).
РаÑÑмоÑÑим ÑледÑÑÑий пÑимеÑ:
function makeFunc() {
var name = "Mozilla";
function displayName() {
alert(name);
}
return displayName;
}
var myFunc = makeFunc();
myFunc();
ÐÑли вÑполниÑÑ ÑÑÐ¾Ñ ÐºÐ¾Ð´, Ñо ÑезÑлÑÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ñакой же, как и вÑполнение init()
из пÑедÑдÑÑего пÑимеÑа: ÑÑÑока "Mozilla" бÑÐ´ÐµÑ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ð° в JavaScript alert диалоге. ЧÑо оÑлиÑÐ°ÐµÑ ÑÑÐ¾Ñ ÐºÐ¾Ð´ и пÑедÑÑавлÑÐµÑ Ð´Ð»Ñ Ð½Ð°Ñ Ð¸Ð½ÑеÑеÑ, Ñак ÑÑо Ñо, ÑÑо внÑÑÑеннÑÑ ÑÑнкÑÐ¸Ñ displayName()
бÑла возвÑаÑена из внеÑней до Ñого, как бÑла вÑполнена.
Ðа пеÑвÑй взглÑд, кажеÑÑÑ Ð½ÐµÐ¾ÑевиднÑм, ÑÑо ÑÑÐ¾Ñ ÐºÐ¾Ð´ пÑавилÑнÑй, но он ÑабоÑаеÑ. РнекоÑоÑÑÑ
ÑзÑкаÑ
пÑогÑаммиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»ÑнÑе пеÑеменнÑе-ÑÑнкÑии ÑÑÑеÑÑвÑÑÑ ÑолÑко во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑÑой ÑÑнкÑии. ÐоÑле завеÑÑÐµÐ½Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ makeFunc()
можно ожидаÑÑ, ÑÑо пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ name болÑÑе не бÑÐ´ÐµÑ Ð´Ð¾ÑÑÑпна. Ðднако, поÑколÑÐºÑ ÐºÐ¾Ð´ пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°ÐµÑ Ð½Ð¾ÑмалÑно ÑабоÑаÑÑ, оÑевидно, ÑÑо ÑÑо не Ñак в ÑлÑÑае JavaScript.
ÐÑиÑина в Ñом, ÑÑо ÑÑнкÑии в JavaScript ÑоÑмиÑÑÑÑ Ñак назÑваемÑе замÑканиÑ. ÐамÑкание â ÑÑо комбинаÑÐ¸Ñ ÑÑнкÑии и лекÑиÑеÑкого окÑÑжениÑ, в коÑоÑом ÑÑа ÑÑнкÑÐ¸Ñ Ð±Ñла обÑÑвлена. ÐÑо окÑÑжение ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· пÑоизволÑного колиÑеÑÑва локалÑнÑÑ
пеÑеменнÑÑ
, коÑоÑÑе бÑли в облаÑÑи дейÑÑÐ²Ð¸Ñ ÑÑнкÑии во вÑÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð·Ð°Ð¼ÑканиÑ. Ð ÑаÑÑмоÑÑенном пÑимеÑе myFunc
â ÑÑо ÑÑÑлка на ÑкземплÑÑ ÑÑнкÑии displayName
, Ñозданной в ÑезÑлÑÑаÑе вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ makeFunc
. ÐкземплÑÑ ÑÑнкÑии displayName
в ÑÐ²Ð¾Ñ Ð¾ÑеÑÐµÐ´Ñ ÑоÑ
ÑанÑÐµÑ ÑÑÑÐ»ÐºÑ Ð½Ð° ÑÐ²Ð¾Ñ Ð»ÐµÐºÑиÑеÑкое окÑÑжение, в коÑоÑом еÑÑÑ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ name
. Ðо ÑÑой пÑиÑине, когда пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð²Ñзов ÑÑнкÑии myFunc
, пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ name
оÑÑаÑÑÑÑ Ð´Ð¾ÑÑÑпной Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑоÑ
ÑанÑннÑй в ней ÑекÑÑ "Mozilla" пеÑедаÑÑÑÑ Ð² alert
.
Ð Ð²Ð¾Ñ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ более инÑеÑеÑнÑй пÑÐ¸Ð¼ÐµÑ â ÑÑнкÑÐ¸Ñ makeAdder
:
function makeAdder(x) {
return function (y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
ÐдеÑÑ Ð¼Ñ Ð¾Ð¿Ñеделили ÑÑнкÑÐ¸Ñ makeAdder(x)
, коÑоÑÐ°Ñ Ð¿Ð¾Ð»ÑÑÐ°ÐµÑ ÐµÐ´Ð¸Ð½ÑÑвеннÑй аÑгÑÐ¼ÐµÐ½Ñ x
и возвÑаÑÐ°ÐµÑ Ð½Ð¾Ð²ÑÑ ÑÑнкÑиÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð¿Ð¾Ð»ÑÑÐ°ÐµÑ ÐµÐ´Ð¸Ð½ÑÑвеннÑй аÑгÑÐ¼ÐµÐ½Ñ y
и возвÑаÑÐ°ÐµÑ ÑÑÐ¼Ð¼Ñ x
и y
.
Ðо ÑÑÑеÑÑÐ²Ñ makeAdder
â ÑÑо ÑабÑика ÑÑнкÑий: она ÑоздаÑÑ ÑÑнкÑии, коÑоÑÑе могÑÑ Ð¿ÑибавлÑÑÑ Ð¾Ð¿ÑеделÑнное знаÑение к ÑÐ²Ð¾ÐµÐ¼Ñ Ð°ÑгÑменÑÑ. РпÑимеÑе вÑÑе Ð¼Ñ Ð¸ÑполÑзÑем наÑÑ ÑабÑиÑнÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð´Ð²ÑÑ
новÑÑ
ÑÑнкÑий â одна пÑибавлÑÐµÑ 5 к ÑÐ²Ð¾ÐµÐ¼Ñ Ð°ÑгÑменÑÑ, вÑоÑÐ°Ñ Ð¿ÑибавлÑÐµÑ 10.
add5
и add10
â ÑÑо пÑимеÑÑ Ð·Ð°Ð¼Ñканий. ÐÑи ÑÑнкÑии делÑÑ Ð¾Ð´Ð½Ð¾ опÑеделение Ñела ÑÑнкÑии, но пÑи ÑÑом они ÑоÑ
ÑанÑÑÑ ÑазлиÑнÑе окÑÑжениÑ. РокÑÑжении ÑÑнкÑии add5
x
â ÑÑо 5, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº в окÑÑжении add10
x
â ÑÑо 10.
ÐамÑÐºÐ°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ñем, ÑÑо позволÑÑÑ ÑвÑзаÑÑ Ð´Ð°Ð½Ð½Ñе (лекÑиÑеÑкое окÑÑжение) Ñ ÑÑнкÑией, коÑоÑÐ°Ñ ÑабоÑÐ°ÐµÑ Ñ ÑÑими даннÑми. ÐÑевидна паÑÐ°Ð»Ð»ÐµÐ»Ñ Ñ Ð¾Ð±ÑекÑно-оÑиенÑиÑованнÑм пÑогÑаммиÑованием, где обÑекÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ Ð½Ð°Ð¼ ÑвÑзаÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе даннÑе (ÑвойÑÑва обÑекÑа) Ñ Ð¾Ð´Ð½Ð¸Ð¼ или неÑколÑкими меÑодами.
СледоваÑелÑно, замÑÐºÐ°Ð½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ Ð²ÐµÐ·Ð´Ðµ, где Ð²Ñ Ð¾Ð±ÑÑно иÑполÑзовали обÑÐµÐºÑ Ñ Ð¾Ð´Ð½Ð¸Ð¼ единÑÑвеннÑм меÑодом.
Такие ÑиÑÑаÑии повÑемеÑÑно вÑÑÑеÑаÑÑÑÑ Ð² web-ÑазÑабоÑке. ÐолÑÑое колиÑеÑÑво front-end кода, коÑоÑÑй Ð¼Ñ Ð¿Ð¸Ñем на JavaScript, оÑновано на обÑабоÑке ÑобÑÑий. ÐÑ Ð¾Ð¿Ð¸ÑÑваем какое-Ñо поведение, а поÑом ÑвÑзÑваем его Ñ ÑобÑÑием, коÑоÑое ÑоздаÑÑÑÑ Ð¿Ð¾Ð»ÑзоваÑелем (напÑимеÑ, клик мÑÑкой или нажаÑие клавиÑи). ÐÑи ÑÑом Ð½Ð°Ñ ÐºÐ¾Ð´ обÑÑно пÑивÑзÑваеÑÑÑ Ðº ÑобÑÑÐ¸Ñ Ð² виде обÑаÑного/оÑвеÑного вÑзова (callback): callback ÑÑнкÑÐ¸Ñ - ÑÑнкÑÐ¸Ñ Ð²ÑполнÑÐµÐ¼Ð°Ñ Ð² оÑÐ²ÐµÑ Ð½Ð° возникновение ÑобÑÑиÑ.
ÐавайÑе ÑаÑÑмоÑÑим пÑакÑиÑеÑкий пÑимеÑ: допÑÑÑим, Ð¼Ñ Ñ Ð¾Ñим добавиÑÑ Ð½Ð° ÑÑÑаниÑÑ Ð½ÐµÑколÑко кнопок, коÑоÑÑе бÑдÑÑ Ð¼ÐµÐ½ÑÑÑ ÑÐ°Ð·Ð¼ÐµÑ ÑекÑÑа. Ðак ваÑианÑ, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑказаÑÑ ÑвойÑÑво font-size на ÑлеменÑе body в пикÑÐµÐ»Ð°Ñ , а заÑем ÑÑÑанавливаÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ð¿ÑоÑÐ¸Ñ ÑлеменÑов ÑÑÑаниÑÑ (ÑÐ°ÐºÐ¸Ñ , как заголовки) Ñ Ð¸ÑполÑзованием оÑноÑиÑелÑнÑÑ ÐµÐ´Ð¸Ð½Ð¸Ñ em:
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 12px;
}
h1 {
font-size: 1.5em;
}
h2 {
font-size: 1.2em;
}
Тогда наÑи кнопки бÑдÑÑ Ð¼ÐµÐ½ÑÑÑ ÑвойÑÑво font-size ÑлеменÑа body, а оÑÑалÑнÑе ÑлеменÑÑ ÑÑÑаниÑÑ Ð¿ÑоÑÑо полÑÑÐ°Ñ ÑÑо новое знаÑение и оÑмаÑÑÑабиÑÑÑÑ ÑÐ°Ð·Ð¼ÐµÑ ÑекÑÑа благодаÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾ÑноÑиÑелÑнÑÑ ÐµÐ´Ð¸Ð½Ð¸Ñ.
ÐÑполÑзÑем ÑледÑÑÑий JavaScript:
function makeSizer(size) {
return function () {
document.body.style.fontSize = size + "px";
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
ТепеÑÑ size12
, size14
, и size16
- ÑÑо ÑÑнкÑии, коÑоÑÑе менÑÑÑ ÑÐ°Ð·Ð¼ÐµÑ ÑекÑÑа в ÑлеменÑе body на знаÑÐµÐ½Ð¸Ñ 12, 14, и 16 пикÑелов, ÑооÑвеÑÑÑвенно. ÐоÑле Ñего Ð¼Ñ ÑеплÑем ÑÑи ÑÑнкÑии на кнопки пÑимеÑно Ñак:
document.getElementById("size-12").onclick = size12;
document.getElementById("size-14").onclick = size14;
document.getElementById("size-16").onclick = size16;
<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>
ÐмÑлÑÑÐ¸Ñ ÑаÑÑнÑÑ
(private) меÑодов Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð·Ð°Ð¼Ñканий
ЯзÑки вÑоде Java позволÑÑÑ Ð½Ð°Ð¼ обÑÑвлÑÑÑ ÑаÑÑнÑе (private) меÑÐ¾Ð´Ñ . ÐÑо знаÑиÑ, ÑÑо они могÑÑ Ð±ÑÑÑ Ð²ÑÐ·Ð²Ð°Ð½Ñ ÑолÑко меÑодами Ñого же клаÑÑа, в коÑоÑом обÑÑвленÑ.
JavaScript не Ð¸Ð¼ÐµÐµÑ Ð²ÑÑÑоенной возможноÑÑи ÑделаÑÑ Ñакое, но ÑÑо можно ÑмÑлиÑоваÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð·Ð°Ð¼ÑканиÑ. ЧаÑÑнÑе меÑÐ¾Ð´Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð½Ðµ ÑолÑко Ñем, ÑÑо огÑаниÑиваÑÑ Ð´Ð¾ÑÑÑп к кодÑ, ÑÑо Ñакже моÑное ÑÑедÑÑво глобалÑной оÑганизаÑии пÑоÑÑÑанÑÑва имÑн, позволÑÑÑее не заÑоÑÑÑÑ Ð¿ÑблиÑнÑй инÑеÑÑÐµÐ¹Ñ Ð²Ð°Ñего кода внÑÑÑенними меÑодами клаÑÑов.
Ðод ниже иллÑÑÑÑиÑÑеÑ, как можно иÑполÑзоваÑÑ Ð·Ð°Ð¼ÑÐºÐ°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿ÑблиÑнÑÑ ÑÑнкÑий, коÑоÑÑе имеÑÑ Ð´Ð¾ÑÑÑп к закÑÑÑÑм Ð¾Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ (private) ÑÑнкÑиÑм и пеÑеменнÑм. Ð¢Ð°ÐºÐ°Ñ Ð¼Ð°Ð½ÐµÑа пÑогÑаммиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð°Ð·ÑваеÑÑÑ Ð¼Ð¾Ð´ÑлÑное пÑогÑаммиÑование:
var Counter = (function () {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function () {
changeBy(1);
},
decrement: function () {
changeBy(-1);
},
value: function () {
return privateCounter;
},
};
})();
alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */
ТÑÑ Ð¼Ð½Ð¾Ð³Ð¾ Ñего поменÑлоÑÑ. РпÑедÑдÑÑем пÑимеÑе каждое замÑкание имело Ñвой ÑобÑÑвеннÑй конÑекÑÑ Ð¸ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (окÑÑжение). ÐдеÑÑ Ð¼Ñ ÑоздаÑм единое окÑÑжение Ð´Ð»Ñ ÑÑÑÑ
ÑÑнкÑий: Counter.increment
, Counter.decrement
, и Counter.value
.
Ðдиное окÑÑжение ÑоздаÑÑÑÑ Ð² Ñеле анонимной ÑÑнкÑии, коÑоÑÐ°Ñ Ð¸ÑполнÑеÑÑÑ Ð² Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¾Ð¿Ð¸ÑаниÑ. ÐÑо окÑÑжение ÑодеÑÐ¶Ð¸Ñ Ð´Ð²Ð° пÑиваÑнÑÑ
ÑлеменÑа: пеÑеменнÑÑ privateCounter
и ÑÑнкÑÐ¸Ñ changeBy(val)
. Ðи один из ÑÑиÑ
ÑлеменÑов не доÑÑÑпен напÑÑмÑÑ, за пÑеделами ÑÑой Ñамой анонимной ÑÑнкÑии. ÐмеÑÑо ÑÑого они могÑÑ Ð¸ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸ÑполÑзоваÑÑÑÑ ÑÑÐµÐ¼Ñ Ð¿ÑблиÑнÑми ÑÑнкÑиÑми, коÑоÑÑе возвÑаÑаÑÑÑÑ Ð°Ð½Ð¾Ð½Ð¸Ð¼Ð½Ñм блоком кода (anonymous wrapper), вÑполнÑемÑм в Ñой же анонимной ÑÑнкÑии.
ÐÑи ÑÑи пÑблиÑнÑе ÑÑнкÑии ÑвлÑÑÑÑÑ Ð·Ð°Ð¼ÑканиÑми, иÑполÑзÑÑÑими обÑий конÑекÑÑ Ð¸ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (окÑÑжение). ÐлагодаÑÑ Ð¼ÐµÑ
Ð°Ð½Ð¸Ð·Ð¼Ñ lexical scoping в Javascript, вÑе они имеÑÑ Ð´Ð¾ÑÑÑп к пеÑеменной privateCounter
и ÑÑнкÑии changeBy
.
ÐамеÑÑÑе, Ð¼Ñ Ð¾Ð¿Ð¸ÑÑваем анонимнÑÑ ÑÑнкÑиÑ, ÑоздаÑÑÑÑ ÑÑÑÑÑик, и ÑÑÑ Ð¶Ðµ запÑÑкаем еÑ, пÑиÑÐ²Ð°Ð¸Ð²Ð°Ñ ÑезÑлÑÑÐ°Ñ Ð¸ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿ÐµÑеменной Counter
. Ðо Ð¼Ñ Ñакже можем не запÑÑкаÑÑ ÑÑÑ ÑÑнкÑÐ¸Ñ ÑÑазÑ, а ÑоÑ
ÑаниÑÑ ÐµÑ Ð² оÑделÑной пеÑеменной, ÑÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ Ð´Ð»Ñ Ð´Ð°Ð»ÑнейÑего ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½ÐµÑколÑкиÑ
ÑÑÑÑÑиков Ð²Ð¾Ñ Ñак:
var makeCounter = function () {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function () {
changeBy(1);
},
decrement: function () {
changeBy(-1);
},
value: function () {
return privateCounter;
},
};
};
var Counter1 = makeCounter();
var Counter2 = makeCounter();
alert(Counter1.value()); /* Alerts 0 */
Counter1.increment();
Counter1.increment();
alert(Counter1.value()); /* Alerts 2 */
Counter1.decrement();
alert(Counter1.value()); /* Alerts 1 */
alert(Counter2.value()); /* Alerts 0 */
ÐамеÑÑÑе, ÑÑо ÑÑÑÑÑики ÑабоÑаÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо дÑÑг Ð¾Ñ Ð´ÑÑга. ÐÑо пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð¿Ð¾ÑомÑ, ÑÑо Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ из ниÑ
в Ð¼Ð¾Ð¼ÐµÐ½Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑÑнкÑией makeCounter()
Ñакже ÑоздавалÑÑ Ñвой оÑделÑнÑй конÑекÑÑ Ð¸ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (окÑÑжение). То еÑÑÑ Ð¿ÑиваÑÐ½Ð°Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ privateCounter
в каждом из ÑÑÑÑÑиков ÑÑо дейÑÑвиÑелÑно оÑделÑнаÑ, ÑамоÑÑоÑÑелÑÐ½Ð°Ñ Ð¿ÐµÑеменнаÑ.
ÐÑполÑзÑÑ Ð·Ð°Ð¼ÑÐºÐ°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ñм обÑазом, Ð²Ñ Ð¿Ð¾Ð»ÑÑаеÑе ÑÑд пÑеимÑÑеÑÑв, обÑÑно аÑÑоÑииÑÑемÑÑ Ñ Ð¾Ð±ÑекÑно-оÑиенÑиÑованнÑм пÑогÑаммиÑованием, ÑÐ°ÐºÐ¸Ñ ÐºÐ°Ðº изолÑÑÐ¸Ñ Ð¸ инкапÑÑлÑÑиÑ.
Создание замÑканий в Ñикле: ÐÑÐµÐ½Ñ ÑаÑÑÐ°Ñ Ð¾ÑибкаÐо Ñого, как в веÑÑии ECMAScript 6 ввели клÑÑевое Ñлово let
, поÑÑоÑнно возникала ÑледÑÑÑÐ°Ñ Ð¿Ñоблема пÑи Ñоздании замÑканий внÑÑÑи Ñикла. РаÑÑмоÑÑим пÑимеÑ:
<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email" /></p>
<p>Name: <input type="text" id="name" name="name" /></p>
<p>Age: <input type="text" id="age" name="age" /></p>
function showHelp(help) {
document.getElementById("help").innerHTML = help;
}
function setupHelp() {
var helpText = [
{ id: "email", help: "ÐÐ°Ñ Ð°Ð´ÑÐµÑ e-mail" },
{ id: "name", help: "ÐаÑе полное имÑ" },
{ id: "age", help: "ÐÐ°Ñ Ð²Ð¾Ð·ÑаÑÑ (Ðам должно бÑÑÑ Ð±Ð¾Ð»ÑÑе 16)" },
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function () {
showHelp(item.help);
};
}
}
setupHelp();
ÐаÑÑив helpText
опиÑÑÐ²Ð°ÐµÑ ÑÑи подÑказки Ð´Ð»Ñ ÑÑÑÑ
полей ввода. Цикл пÑÐ¾Ð±ÐµÐ³Ð°ÐµÑ ÑÑи опиÑÐ°Ð½Ð¸Ñ Ð¿Ð¾ оÑеÑеди и Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ из полей ввода опÑеделÑеÑ, ÑÑо пÑи возникновении ÑобÑÑÐ¸Ñ onfocus
Ð´Ð»Ñ ÑÑого ÑлеменÑа должна вÑзÑваÑÑÑÑ ÑÑнкÑиÑ, показÑваÑÑÐ°Ñ ÑооÑвеÑÑÑвÑÑÑÑÑ Ð¿Ð¾Ð´ÑказкÑ.
ÐÑли Ð²Ñ Ð·Ð°Ð¿ÑÑÑиÑе ÑÑÐ¾Ñ ÐºÐ¾Ð´, Ñо ÑвидиÑе, ÑÑо он ÑабоÑÐ°ÐµÑ Ð½Ðµ Ñак, как Ð¼Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼ инÑÑиÑивно. Ðакое поле Ð²Ñ Ð±Ñ Ð½Ð¸ вÑбÑали, в каÑеÑÑве подÑказки вÑегда бÑÐ´ÐµÑ Ð²ÑÑвеÑиваÑÑÑÑ ÑообÑение о возÑаÑÑе.
ÐÑоблема в Ñом, ÑÑо ÑÑнкÑии, пÑиÑвоеннÑе как обÑабоÑÑики ÑобÑÑÐ¸Ñ onfocus
, ÑвлÑÑÑÑÑ Ð·Ð°Ð¼ÑканиÑми. Ðни ÑоÑÑоÑÑ Ð¸Ð· опиÑÐ°Ð½Ð¸Ñ ÑÑнкÑии и конÑекÑÑа иÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (окÑÑжениÑ), ÑнаÑледованного Ð¾Ñ ÑÑнкÑии setupHelp
. ÐÑло Ñоздано ÑÑи замÑканиÑ, но вÑе они бÑли ÑÐ¾Ð·Ð´Ð°Ð½Ñ Ñ Ð¾Ð´Ð½Ð¸Ð¼ и Ñем же конÑекÑÑом иÑполнениÑ. РмоменÑÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½Ð¾Ð²ÐµÐ½Ð¸Ñ ÑобÑÑÐ¸Ñ onfocus
Ñикл Ñже давно оÑÑабоÑал, а знаÑиÑ, пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ item
(одна и Ñа же Ð´Ð»Ñ Ð²ÑеÑ
ÑÑÑÑ
замÑканий) ÑказÑÐ²Ð°ÐµÑ Ð½Ð° поÑледний ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива, коÑоÑÑй как Ñаз в поле возÑаÑÑа.
РкаÑеÑÑве ÑеÑÐµÐ½Ð¸Ñ Ð² ÑÑом ÑлÑÑае можно пÑедложиÑÑ Ð¸ÑполÑзование ÑÑнкÑии, ÑабÑиÑной ÑÑнкÑии (function factory), как Ñже бÑло опиÑано вÑÑе в пÑимеÑÐ°Ñ :
function showHelp(help) {
document.getElementById("help").innerHTML = help;
}
function makeHelpCallback(help) {
return function () {
showHelp(help);
};
}
function setupHelp() {
var helpText = [
{ id: "email", help: "ÐÐ°Ñ Ð°Ð´ÑÐµÑ e-mail" },
{ id: "name", help: "ÐаÑе полное имÑ" },
{ id: "age", help: "ÐÐ°Ñ Ð²Ð¾Ð·ÑаÑÑ (Ðам должно бÑÑÑ Ð±Ð¾Ð»ÑÑе 16)" },
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
}
}
setupHelp();
ÐÐ¾Ñ ÑÑо ÑабоÑÐ°ÐµÑ ÐºÐ°Ðº ÑледÑеÑ. ÐмеÑÑо Ñого, ÑÑÐ¾Ð±Ñ Ð´ÐµÐ»Ð¸ÑÑ Ð½Ð° вÑеÑ
одно окÑÑжение, ÑÑнкÑÐ¸Ñ makeHelpCallback
ÑоздаÑÑ ÐºÐ°Ð¶Ð´Ð¾Ð¼Ñ Ð¸Ð· замÑканий ÑÐ²Ð¾Ñ ÑобÑÑвенное, в коÑоÑом пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ item
ÑказÑÐ²Ð°ÐµÑ Ð½Ð° пÑавилÑнÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÑива helpText
.
Ðе нÑжно без Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи ÑоздаваÑÑ ÑÑнкÑии внÑÑÑи ÑÑнкÑий в ÑÐµÑ ÑлÑÑаÑÑ , когда замÑÐºÐ°Ð½Ð¸Ñ Ð½Ðµ нÑжнÑ. ÐÑполÑзование ÑÑой ÑÐµÑ Ð½Ð¸ÐºÐ¸ ÑвелиÑÐ¸Ð²Ð°ÐµÑ ÑÑÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ðº пÑоизводиÑелÑноÑÑи как в ÑаÑÑи ÑкоÑоÑÑи, Ñак и в ÑаÑÑи поÑÑÐµÐ±Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼ÑÑи.
Ðак пÑимеÑ, пÑи напиÑании нового клаÑÑа еÑÑÑ ÑмÑÑл помеÑаÑÑ Ð²Ñе меÑÐ¾Ð´Ñ Ð² пÑоÑоÑип его обÑекÑа, а не опиÑÑваÑÑ Ð¸Ñ Ð² ÑекÑÑе конÑÑÑÑкÑоÑа. ÐÑли ÑделаÑÑ Ð¿Ð¾-дÑÑгомÑ, Ñо пÑи каждом Ñоздании обÑекÑа Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ бÑÐ´ÐµÑ Ñоздан Ñвой ÑкземплÑÑ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ из меÑодов, вмеÑÑо Ñого, ÑÑÐ¾Ð±Ñ Ð½Ð°ÑледоваÑÑ Ð¸Ñ Ð¸Ð· пÑоÑоÑипа.
ÐавайÑе ÑаÑÑмоÑÑим не оÑÐµÐ½Ñ Ð¿ÑакÑиÑнÑй, но показаÑелÑнÑй пÑимеÑ:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
this.getName = function () {
return this.name;
};
this.getMessage = function () {
return this.message;
};
}
ÐоÑколÑÐºÑ Ð²ÑÑепÑиведÑннÑй код никак не иÑполÑзÑÐµÑ Ð¿ÑеимÑÑеÑÑва замÑканий, его можно пеÑепиÑаÑÑ ÑледÑÑÑим обÑазом:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
MyObject.prototype = {
getName: function () {
return this.name;
},
getMessage: function () {
return this.message;
},
};
ÐеÑÐ¾Ð´Ñ Ð²ÑнеÑÐµÐ½Ñ Ð² пÑоÑоÑип. Тем не менее, пеÑеопÑеделÑÑÑ Ð¿ÑоÑоÑип â Ñамо по Ñебе ÑвлÑеÑÑÑ Ð¿Ð»Ð¾Ñ Ð¾Ð¹ пÑивÑÑкой, поÑÑÐ¾Ð¼Ñ Ð´Ð°Ð²Ð°Ð¹Ñе пеÑепиÑем вÑÑ Ñак, ÑÑÐ¾Ð±Ñ Ð½Ð¾Ð²Ñе меÑÐ¾Ð´Ñ Ð¿ÑоÑÑо добавилиÑÑ Ðº Ñже ÑÑÑеÑÑвÑÑÑÐµÐ¼Ñ Ð¿ÑоÑоÑипÑ.
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
MyObject.prototype.getName = function () {
return this.name;
};
MyObject.prototype.getMessage = function () {
return this.message;
};
Ðод вÑÑе можно ÑделаÑÑ Ð°ÐºÐºÑÑаÑнее:
function MyObject(name, message) {
this.name = name.toString();
this.message = message.toString();
}
(function () {
this.getName = function () {
return this.name;
};
this.getMessage = function () {
return this.message;
};
}).call(MyObject.prototype);
Ð Ð¾Ð±Ð¾Ð¸Ñ Ð¿ÑимеÑÐ°Ñ Ð²ÑÑе меÑÐ¾Ð´Ñ Ð¾Ð¿ÑеделÑÑÑÑÑ Ð¾Ð´Ð¸Ð½ Ñаз â в пÑоÑоÑипе. РвÑе обÑекÑÑ, иÑполÑзÑÑÑие даннÑй пÑоÑоÑип, бÑдÑÑ Ð¸ÑполÑзоваÑÑ ÑÑо опÑеделение без дополниÑелÑного ÑаÑÑ Ð¾Ð´Ð° вÑÑиÑлиÑелÑнÑÑ ÑеÑÑÑÑов. СмоÑÑиÑе подÑобное опиÑание в ÑÑаÑÑе ÐодÑобнее об обÑекÑной модели.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4