Тут важливо зазначити, що оскільки Javascript - це динамічна мова, кожен об’єкт, по суті, є лише прославленою хеш-картою ( за кількома винятками ). І все в об'єкті Javascript можна отримати двома способами - нотацією дужок і нотацією крапок.
Я швидко перейду на два позначення, відповідаючи на першу частину вашого питання, а потім перейду до другої частини.
Нотація дужки
Цей режим більше схожий на доступ до хешмапів та масивів іншими мовами програмування. Ви можете отримати доступ до будь-якого компонента (даних (включаючи інші об'єкти) чи функції) за допомогою цього синтаксису.
Це саме те, що ти робиш у своєму прикладі. У вас є 'a'
, що є рядком (а не буквеним символом, як це було б у такій мові, як C ++).
Використовуючи позначення дужок, ви отримуєте доступ до його toUpperCase
методу. Але доступ до нього все ще недостатній; просто введення alert
, наприклад, у Javascript, метод не викликає. Це просто просте твердження. Для виклику функції потрібно додати круглі дужки: alert()
показує просте діалогове вікно, що містить undefined
, оскільки воно не отримало жодних параметрів. Тепер ми можемо використовувати ці знання для розшифровки вашого коду, який стає:
alert('a'.toUpperCase());
Що набагато читабельніше.
Насправді, хороший спосіб зрозуміти це трохи краще - це виконати наступний Javascript:
alert(alert)
Це викликає alert
, передаючи йому об'єкт функції, також alert
, не виконуючи також другого попередження. Показано (як мінімум, у Chrome 26):
function alert() { [native code] }
Дзвінки:
alert(alert())
показує два послідовних вікна повідомлень, що містять undefined
. Це легко пояснити: внутрішній alert()
виконується спочатку, показує undefined
(бо не мав жодних параметрів) і нічого не повертає. Зовнішнє сповіщення отримує зворотне значення внутрішнього сповіщення - яке є нічого, а також відображається undefined
у вікні повідомлення.
Спробуйте всі випадки на jsFiddle!
Точкове позначення
Це більш стандартний підхід, який дозволяє отримати доступ до членів об'єкта за допомогою .
оператора dot ( ). Ось як виглядатиме ваш код у крапкових позначеннях:
alert('a'.toUpperCase())
Набагато читабельніший. Отже, коли нам слід використовувати позначення крапок, а коли слід використовувати позначення дужок?
Порівняння
Основна відмінність двох методів - семантична. Є ще деякі деталі, але я дістанусь до них за секунду. Найголовніше - це те, що ви насправді хочете зробити. Основне правило полягає в тому, що ви використовуєте крапкові позначення для добре встановлених полів і методів, якими володіє об'єкт, і дужки-позначення, коли ви фактично використовуєте ваш об'єкт як хеш-карту .
Чудовий приклад того, чому це правило є настільки важливим, може бути показаний у вашому прикладі - оскільки код використовує позначення дужок у місці, де нотація крапок була б набагато більш розумною, це робить код важче читати. І це погано, адже код читається набагато більше разів, ніж написано .
У деяких випадках вам доводиться використовувати позначення дужок, навіть якщо використання позначень крапок було більш розумним:
якщо член об’єкта має ім'я, що містить один або кілька пробілів або будь-які інші спеціальні символи, ви не можете використовувати позначення крапок: foo.some method()
не працює, але foo["some method"]()
робить;
якщо вам потрібно динамічно отримати доступ до членів об’єкта, ви також застрягли, використовуючи позначення дужок;
Приклад:
for(var i = 0; i < 10; ++i) {
foo["method" + i]();
}
Суть полягає в тому, що ви повинні використовувати синтаксис дужок при використанні об'єкта як хеш-карти ( foods["burger"].eat()
) і крапки синтаксису під час роботи з "фактичними" полями та методами ( enemy.kill()
). Оскільки Javascript є динамічною мовою, лінія між "фактичними" полями та методами об'єкта та "іншими" даними, що зберігаються всередині, може бути досить розмитою. Але поки ви не змішуєте їх заплутаними способами, вам слід добре.
Тепер, на решту вашого питання (нарешті!: P).
як я можу бути впевненим, що метод завжди буде членом obj
Ви не можете. Спробуй це. Спробуйте зателефонувати derp
на рядок. Ви отримаєте помилку в рядках:
Uncaught TypeError: Object a has no method 'derp'
Це своєрідна загальна функція викликати будь-які методи на будь-якому об’єкті. Але чи означає це, що зазначений метод вже буде неявним членом зазначеного об'єкта?
Так, у вашому випадку це мало бути. Інакше ви стикаєтесь з помилкою, про яку я згадував вище. Однак вам не потрібно використовувати return obj[method]();
цю callMethod()
функцію. Ви можете додати власну функціональність, яку потім використовує функція карти. Ось важко закодований метод, який перетворює всі літери у великі літери:
function makeCap()
{
return function(obj) {
return obj.toUpperCase();
}
}
var caps2 = map(['a', 'b', 'c'], makeCap()); // ['A','B','C']
console.log(caps2)
Код у підручнику, до якого ви пов’язані, використовує часткові функції . Вони самі по собі хитрі поняття. Читання детальніше про цю тему має допомогти зробити речі яснішими, ніж я коли-небудь можу їх зробити.
Примітка: це код функції карти, який використовується кодом у питанні, джерело тут .
function map(arr, iterator) {
var narr = [];
for (var i = 0; i < arr.length; i++) narr.push(iterator(arr[i], i));
return narr;
}
arr[5]
. Якщо числа , де дійсні імена ідентифікаторів можна використовувати точкову нотацію:arr.5
.