ÐÑа ÑÑаÑÑÑ Ð¾Ñ Ð²Ð°ÑÑÐ²Ð°ÐµÑ Ð¿ÑодвинÑÑÑÑ ÑемÑ, ÑÑÐ¾Ð±Ñ Ð»ÑÑÑе понÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе неÑÑандаÑÑнÑе ÑлÑÑаи.
Ðна неÑилÑно важна. Ðногие опÑÑнÑе ÑазÑабоÑÑики пÑекÑаÑно живÑÑ, даже не подозÑÐµÐ²Ð°Ñ Ð¾Ð± ÑÑом. ЧиÑайÑе далÑÑе, еÑли Ñ Ð¾ÑиÑе ÑзнаÑÑ, как вÑе ÑабоÑÐ°ÐµÑ Ð¿Ð¾Ð´ капоÑом.
ÐекоÑоÑÑе Ñ
иÑÑÑе ÑпоÑÐ¾Ð±Ñ Ð²Ñзова меÑода пÑиводÑÑ Ðº поÑеÑе знаÑÐµÐ½Ð¸Ñ this, напÑимеÑ:
let user = {
name: "Ðжон",
hi() { alert(this.name); },
bye() { alert("Ðока"); }
};
user.hi(); // Ðжон (пÑоÑÑой вÑзов меÑода ÑабоÑÐ°ÐµÑ Ñ
оÑоÑо)
// ÑепеÑÑ Ð´Ð°Ð²Ð°Ð¹Ñе попÑобÑем вÑзÑваÑÑ user.hi или user.bye
// в завиÑимоÑÑи Ð¾Ñ Ð¸Ð¼ÐµÐ½Ð¸ полÑзоваÑÐµÐ»Ñ user.name
(user.name == "Ðжон" ? user.hi : user.bye)(); // ÐÑибка!
РпоÑледней ÑÑÑоÑке кода иÑполÑзÑеÑÑÑ ÑÑловнÑй опеÑаÑÐ¾Ñ ?, коÑоÑÑй опÑеделÑеÑ, какой бÑÐ´ÐµÑ Ð²Ñзван меÑод (user.hi или user.bye) в завиÑимоÑÑи Ð¾Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑÑловиÑ. Рданном ÑлÑÑае бÑÐ´ÐµÑ Ð²ÑбÑан user.hi.
ÐаÑем меÑод ÑÑÑ Ð¶Ðµ вÑзÑваеÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñкобок (). Ðо вÑзов не ÑабоÑÐ°ÐµÑ ÐºÐ°Ðº положено!
ÐÑ Ð¼Ð¾Ð¶ÐµÑе видеÑÑ, ÑÑо пÑи вÑзове бÑÐ´ÐµÑ Ð¾Ñибка, поÑÐ¾Ð¼Ñ ÑÑо знаÑением "this" внÑÑÑи ÑÑнкÑии ÑÑановиÑÑÑ undefined (полагаем, ÑÑо Ñ Ð½Ð°Ñ ÑÑÑогий Ñежим).
Так ÑабоÑÐ°ÐµÑ (доÑÑÑп к меÑÐ¾Ð´Ñ Ð¾Ð±ÑекÑа ÑеÑез ÑоÑкÑ):
user.hi();
Так Ñже не ÑабоÑÐ°ÐµÑ (вÑзÑваемÑй меÑод вÑÑиÑлÑеÑÑÑ):
(user.name == "John" ? user.hi : user.bye)(); // ÐÑибка!
ÐоÑемÑ? ÐÑли Ð¼Ñ Ñ
оÑим понÑÑÑ, поÑÐµÐ¼Ñ Ñак пÑоиÑÑ
одиÑ, давайÑе ÑазбеÑÑмÑÑ (заглÑнем под капоÑ), как ÑабоÑÐ°ÐµÑ Ð²Ñзов меÑодов (obj.method()).
СÑÑлоÑнÑй Ñип: обÑÑÑнение
ÐÑиÑмоÑÑевÑиÑÑ Ð¿Ð¾Ð±Ð»Ð¸Ð¶Ðµ, в вÑÑажении obj.method() можно замеÑиÑÑ Ð´Ð²Ðµ опеÑаÑии:
- СнаÑала опеÑаÑÐ¾Ñ ÑоÑка
'.'возвÑаÑÐ°ÐµÑ ÑвойÑÑво обÑекÑа â его меÑод (obj.method). - ÐаÑем Ñкобки
()вÑзÑваÑÑ ÑÑÐ¾Ñ Ð¼ÐµÑод (иÑполнÑеÑÑÑ ÐºÐ¾Ð´ меÑода).
ÐÑак, каким же обÑазом инÑоÑмаÑÐ¸Ñ Ð¾ this пеÑедаÑÑÑÑ Ð¸Ð· пеÑвой ÑаÑÑи во вÑоÑÑÑ?
ÐÑли Ð¼Ñ Ð¿Ð¾Ð¼ÐµÑÑим ÑÑи опеÑаÑии в оÑделÑнÑе ÑÑÑоки, Ñо знаÑение this, еÑÑеÑÑвенно, бÑÐ´ÐµÑ Ð¿Ð¾ÑеÑÑно:
let user = {
name: "John",
hi() { alert(this.name); }
};
// Ñазделим полÑÑение меÑода обÑекÑа и его вÑзов в ÑазнÑÑ
ÑÑÑокаÑ
let hi = user.hi;
hi(); // ÐÑибка, поÑÐ¾Ð¼Ñ ÑÑо знаÑением this ÑвлÑеÑÑÑ undefined
ÐдеÑÑ hi = user.hi ÑоÑ
ÑанÑÐµÑ ÑÑнкÑÐ¸Ñ Ð² пеÑеменной, и далее в поÑледней ÑÑÑоке она вÑзÑваеÑÑÑ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ Ñама по Ñебе, без обÑекÑа, Ñак ÑÑо Ð½ÐµÑ this.
ÐÐ»Ñ ÑабоÑÑ Ð²Ñзовов Ñипа user.hi(), JavaScript иÑполÑзÑÐµÑ ÑÑÑк â ÑоÑка '.' возвÑаÑÐ°ÐµÑ Ð½Ðµ ÑÐ°Ð¼Ñ ÑÑнкÑиÑ, а ÑпеÑиалÑное знаÑение «ÑÑÑлоÑного Ñипа», назÑваемого Reference Type.
ÐÑÐ¾Ñ ÑÑÑлоÑнÑй Ñип (Reference Type) ÑвлÑеÑÑÑ Ð²Ð½ÑÑÑенним Ñипом. ÐÑ Ð½Ðµ можем Ñвно иÑполÑзоваÑÑ ÐµÐ³Ð¾, но он иÑполÑзÑеÑÑÑ Ð²Ð½ÑÑÑи ÑзÑка.
ÐнаÑение ÑÑÑлоÑного Ñипа â ÑÑо «ÑÑиплеÑ»: комбинаÑÐ¸Ñ Ð¸Ð· ÑÑÑÑ
знаÑений (base, name, strict), где:
baseâ ÑÑо обÑекÑ.nameâ ÑÑо Ð¸Ð¼Ñ ÑвойÑÑва обÑекÑа.strictâ ÑÑо Ñежим иÑполнениÑ. ЯвлÑеÑÑÑ true, еÑли дейÑÑвÑÐµÑ ÑÑÑогий Ñежим (use strict).
РезÑлÑÑаÑом доÑÑÑпа к ÑвойÑÑÐ²Ñ user.hi ÑвлÑеÑÑÑ Ð½Ðµ ÑÑнкÑиÑ, а знаÑение ÑÑÑлоÑного Ñипа. ÐÐ»Ñ user.hi в ÑÑÑогом Ñежиме оно бÑÐ´ÐµÑ Ñаким:
// знаÑение ÑÑÑлоÑного Ñипа (Reference Type)
(user, "hi", true)
Ðогда Ñкобки () пÑименÑÑÑÑÑ Ðº знаÑÐµÐ½Ð¸Ñ ÑÑÑлоÑного Ñипа (пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð²Ñзов), Ñо они полÑÑаÑÑ Ð¿Ð¾Ð»Ð½ÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð± обÑекÑе и его меÑоде, и могÑÑ Ð¿Ð¾ÑÑавиÑÑ Ð¿ÑавилÑнÑй this (user в данном ÑлÑÑае, по base).
СÑÑлоÑнÑй Ñип â иÑклÑÑиÑелÑно внÑÑÑенний, пÑомежÑÑоÑнÑй, иÑполÑзÑемÑй, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑедаÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ñ ÑоÑки . до вÑзÑваÑÑиÑ
Ñкобок ().
ÐÑи лÑбой дÑÑгой опеÑаÑии, напÑимеÑ, пÑиÑваивании hi = user.hi, ÑÑÑлоÑнÑй Ñип заменÑеÑÑÑ Ð½Ð° ÑобÑÑвенно знаÑение user.hi (ÑÑнкÑиÑ), и далÑÑе ÑабоÑа Ñже идÑÑ ÑолÑко Ñ Ð½ÐµÐ¹. ÐоÑÑÐ¾Ð¼Ñ Ð´Ð°Ð»ÑнейÑий вÑзов пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ñже без this.
Таким обÑазом, знаÑение this пеÑедаÑÑÑÑ Ð¿ÑавилÑно, ÑолÑко еÑли ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð½Ð°Ð¿ÑÑмÑÑ Ñ Ð¸ÑполÑзованием ÑинÑакÑиÑа ÑоÑки obj.method() или квадÑаÑнÑÑ
Ñкобок obj['method']() (они делаÑÑ Ñо же Ñамое). СÑÑеÑÑвÑÑÑ ÑазлиÑнÑе ÑпоÑÐ¾Ð±Ñ ÑеÑÐµÐ½Ð¸Ñ ÑÑой пÑоблемÑ: одним из ÑакиÑ
ÑвлÑеÑÑÑ func.bind().
ÐÑого
СÑÑлоÑнÑй Ñип â ÑÑо внÑÑÑенний Ñип ÑзÑка.
ЧÑение ÑвойÑÑва, напÑимеÑ, Ñ ÑоÑкой . в obj.method() возвÑаÑÐ°ÐµÑ Ð½Ðµ ÑоÑное знаÑение ÑвойÑÑва, а ÑпеÑиалÑное знаÑение «ÑÑÑлоÑного Ñипа», в коÑоÑом Ñ
ÑаниÑÑÑ ÐºÐ°Ðº знаÑение ÑвойÑÑва, Ñак и обÑекÑ, из коÑоÑого оно бÑло взÑÑо.
ÐÑо нÑжно Ð´Ð»Ñ Ð¿Ð¾ÑледÑÑÑего вÑзова меÑода (), ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¾Ð±ÑÐµÐºÑ Ð¸ ÑÑÑановиÑÑ Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ this.
ÐÐ»Ñ Ð²ÑÐµÑ Ð¾ÑÑалÑнÑÑ Ð¾Ð¿ÐµÑаÑий ÑÑÑлоÑнÑй Ñип авÑомаÑиÑеÑки ÑÑановиÑÑÑ Ð·Ð½Ð°Ñением ÑвойÑÑва (в наÑем ÑлÑÑае ÑÑнкÑией).
ÐÑÑ Ð¼ÐµÑ Ð°Ð½Ð¸ÐºÐ° ÑкÑÑÑа Ð¾Ñ Ð½Ð°ÑÐ¸Ñ Ð³Ð»Ð°Ð·. ÐÑо Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение ÑолÑко в оÑобÑÑ ÑлÑÑаÑÑ , напÑимеÑ, когда меÑод динамиÑеÑки извлекаеÑÑÑ Ð¸Ð· обÑекÑа Ñ Ð¸ÑполÑзованием вÑÑажениÑ.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)