Crockford багато зробив для популяризації хороших методик JavaScript. Його висловлена позиція щодо ключових елементів мови викликала багато корисних дискусій. Однак, існує надто багато людей, які сприймають кожне проголошення «поганого» або «шкідливого» як євангеліє, відмовляючись дивитись поза думкою однієї людини. Часом це може трохи засмучувати.
Використання функціональних можливостей, що надаються new
ключовим словом, має ряд переваг перед побудовою кожного об'єкта з нуля:
- Прототип успадкування . Хоча часто на це дивляться з поєднанням підозр та насмішок з боку тих, хто звик до мов OO, заснованих на класах, рідна техніка успадкування JavaScript - це простий та дивно ефективний засіб повторного використання коду. І нове ключове слово - це канонічний (і єдиний доступний кросплатформенний) засіб його використання.
- Продуктивність. Це побічний ефект # 1: якщо я хочу додати 10 методів для кожного об'єкта я створюю, я міг би просто написати функцію створення , який вручну присвоює кожен метод для кожного нового об'єкта ... Або я міг би віднести їх до функція створення
prototype
та використання new
для маркування нових об'єктів. Це не тільки швидше (не потрібен код для кожного методу в прототипі), він дозволяє уникнути повітряного кулірування кожного об'єкта з окремими властивостями для кожного методу. На більш повільних машинах (або, особливо, повільніших інтерпретаторах JS), коли створюється багато об'єктів, це може означати значну економію часу та пам'яті.
І так, new
є один вирішальний недолік, вміло описаний іншими відповідями: якщо ви забудете його використовувати, ваш код порушиться без попередження. На щастя, цей недолік легко усунути - просто додайте трохи функції до самої функції:
function foo()
{
// if user accidentally omits the new keyword, this will
// silently correct the problem...
if ( !(this instanceof foo) )
return new foo();
// constructor logic follows...
}
Тепер ви можете мати переваги, new
не турбуючись про проблеми, викликані випадковим неправильним використанням. Ви навіть можете додати твердження до чека, якщо думка про розбитий код беззвучно працює. Або, як дехто прокоментував, використовуйте чек, щоб ввести виняток під час виконання:
if ( !(this instanceof arguments.callee) )
throw new Error("Constructor called as a function");
(Зверніть увагу, що цей фрагмент здатний уникнути жорсткого кодування імені функції конструктора, оскільки на відміну від попереднього прикладу, він не потребує фактичної інстанції об'єкта - тому його можна копіювати у кожну цільову функцію без змін.)
Джон Резіг детально розглядає цю методику у своєму простому "Послідовні" "Моментальний пошук" , а також включає засоби побудови такої поведінки у свої "класи" за замовчуванням. Безумовно, варто прочитати ... як і його майбутня книга " Секрети JavaScript ніндзя" , яка знаходить приховане золото в цій та багатьох інших "шкідливих" рисах мови JavaScript ( розділ про with
це особливо просвічує тих, хто спочатку звільнив. ця дуже злісна особливість, як трюк).