Чи вважається "новим" ключове слово JavaScript шкідливим? [зачинено]


568

В іншому запитанні користувач вказав, що newключове слово небезпечне для використання, і запропонував рішення для створення об’єктів, які не використовуються new. Я не вірив, що це правда, здебільшого тому, що я використовував прототипи, Scriptaculous та інші відмінні бібліотеки JavaScript, і кожен з них використовував newключове слово.

Незважаючи на це, я вчора дивився розмову Дугласа Крокфорда в театрі YUI, і він сказав саме те саме, що він більше не використовував newключове слово у своєму коді ( Crockford на JavaScript - Act III: Функція The Ultimate - 50:23 хвилин ).

Чи погано використовувати newключове слово? Які переваги та недоліки його використання?


90
Використовувати нове ключове слово НЕ "погано". Але якщо ви це забудете, ви будете викликати конструктор об'єктів як звичайну функцію. Якщо ваш конструктор не перевіряє контекст його виконання, він не помітить, що "це" вказує на інший об'єкт (як правило, глобальний об'єкт) замість нового екземпляра. Тому ваш конструктор додасть властивості та методи до глобального об'єкта (вікна). Якщо ви завжди перевіряєте, що "це" є примірником вашого об'єкта у функції об'єкта, то у вас ніколи не виникне ця проблема.
Крістіан Б

5
Я цього не розумію. З одного боку, Дуг перешкоджає використанню new. Але коли ви дивитесь на бібліотеку YUI Ви повинні користуватися newскрізь. Такі як var myDataSource = new Y.DataSource.IO({source:"./myScript.php"}); .
aditya_gaur

2
@aditya_gaur Це тому, що якщо вам потрібна ініціалізація об'єкта, вам доведеться зламати initметод, якщо ви використовуєте Object.createпідхід, і викликати його після. Набагато простіше просто використовувати те, newщо робить і те, і інше, встановлює прототип ланцюга і викликає якийсь код ініціалізатора.
Хуан Мендес

67
Я не думаю, що це мало бути закритим. Так, це, ймовірно, надихне деяку противентиляторну отруту Крокфорда, але ми говоримо про популярні поради, щоб уникнути головних мовних особливостей. Механізм, завдяки якому кожен об’єкт JQuery майже нічого не важить (де це стосується пам'яті), не передбачає використання "нового" ключового слова. Віддайте перевагу заводським методам постійно викликати нові, але не різко знижуйте свої архітектурні параметри та потенціал продуктивності, використовуючи лише об'єктивні літерали. Вони мають своє місце і конструктори мають своє місце. Це датовані і неприємні поради.
Ерік Реппен

2
TLDR: Використовувати newне небезпечно. Опускати newнебезпечно, а значить, і погано . Але в ES5 ви можете використовувати суворий режим , який захищає вас від небезпеки та багатьох інших.
jkdev

Відповіді:


603

Crockford багато зробив для популяризації хороших методик JavaScript. Його висловлена ​​позиція щодо ключових елементів мови викликала багато корисних дискусій. Однак, існує надто багато людей, які сприймають кожне проголошення «поганого» або «шкідливого» як євангеліє, відмовляючись дивитись поза думкою однієї людини. Часом це може трохи засмучувати.

Використання функціональних можливостей, що надаються newключовим словом, має ряд переваг перед побудовою кожного об'єкта з нуля:

  1. Прототип успадкування . Хоча часто на це дивляться з поєднанням підозр та насмішок з боку тих, хто звик до мов OO, заснованих на класах, рідна техніка успадкування JavaScript - це простий та дивно ефективний засіб повторного використання коду. І нове ключове слово - це канонічний (і єдиний доступний кросплатформенний) засіб його використання.
  2. Продуктивність. Це побічний ефект # 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це особливо просвічує тих, хто спочатку звільнив. ця дуже злісна особливість, як трюк).


96
if (! (this instanceof argument.callee)) кидають помилку ("Конструктор викликається функцією"); // Більш загальне, не потрібно знання імені конструкторів, змусити користувача виправити код.
десь

5
Якщо ви турбуєтесь про ефективність роботи - а у вас справді є причина - тоді взагалі не робіть перевірки. Або пам'ятайте про використання new, або використовуйте функцію обгортки, щоб запам'ятати її для вас. Я підозрюю, що якщо ви знаходитесь в точці, де це має значення, ви вже вичерпали інші оптимізації, такі як запам'ятовування, тому ваші дзвінки про створення все одно будуть локалізовані ...
Shog9

65
Використання arguments.calleeдля перевірки, чи вас викликали, newможе бути не дуже хорошим, оскільки arguments.calleeвоно не доступне в суворому режимі. Краще використовувати назву функції.
Шон Макміллан

69
Якщо я неправильно написав ідентифікатор, мій код порушується. Чи не слід використовувати ідентифікатори? Не використовувати, newтому що ви можете забути написати це у своєму коді, так само достеменно, як і мій приклад.
Томас Едінг

16
Якщо включити строгий режим, якщо ви забули використовувати новий ви отримаєте виняток , якщо ви намагаєтеся використовувати це: yuiblog.com/blog/2010/12/14/strict-mode-is-coming-to-town Тобто простіше, ніж додати екземпляр перевірки до кожного конструктора.
stephenbez

182

Я щойно прочитав деякі частини його книги Крокфордса "Javascript: хороші частини". У мене виникає відчуття, що він вважає все, що коли-небудь вкусило його шкідливим:

Про падіння перемикача:

Я ніколи не допускаю переходу випадків перемикання на наступний випадок. Одного разу я знайшов помилку в своєму коді, спричинену ненавмисним падінням одразу після того, як виступив з енергійною промовою про те, чому провалитися іноді було корисно. (стор. 97, ISBN 978-0-596-51774-8)

Про ++ та -

Відомо, що оператори ++ (приріст) та - (декремент) сприяють поганому коду, заохочуючи надмірну хитрість. Вони поступаються лише несправній архітектурі в тому, що дозволяє включити віруси та інші загрози для безпеки. (стор. 122)

Про нове:

Якщо ви забули включити новий префікс при виконанні функції конструктори, то це НЕ буде прив'язане до нового об'єкту. На жаль, це буде прив’язано до глобального об'єкта, тому замість того, щоб збільшити новий об’єкт, ви будете зациклюватися на глобальних змінних. Це справді погано. Немає попередження про компіляцію та попередження про час виконання. (стор. 49)

Є більше, але сподіваюся, ви отримаєте картину.

Моя відповідь на ваше запитання: Ні, це не шкідливо. але якщо ви забудете використовувати його, коли вам слід, у вас можуть виникнути проблеми. Якщо ви розвиваєтеся в хороших умовах, ви це помічаєте.

Оновлення

Приблизно через рік після написання цієї відповіді було випущено 5-е видання ECMAScript із підтримкою суворого режиму . У суворому режимі thisбільше не прив’язаний до глобального об'єкта, а до undefined.


3
Я повністю згоден. Рішення: Завжди документуйте, як користувачі повинні створювати інстанцію ваших об'єктів. Скористайтеся прикладом, і користувачі, швидше за все, виріжуть / вставлять. У кожній мові є конструкції / особливості, якими можна неправомірно користуватися, що призводить до незвичної / несподіваної поведінки. Це не робить їх шкідливими.
nicerobot

45
Існує умова завжди запускати конструктори з верхньої літери, а всі інші функції - з малої літери.
десь

61
Я щойно зрозумів, що Крокфорд не вважає ВСЕ шкідливим ... Я не знаю, скільки разів я створив інфінітивний цикл, тому що забув збільшити змінну ...
десь

5
Те саме стосується ++, -. Вони висловлюють саме те, що я маю намір найяснішою можливою мовою. Я люблю їх! Перепад комутаторів може комусь зрозуміти, але я з цим втомився. Я використовую їх, коли вони явно чіткіші (бо каламбур, не втримався).
ПЕЗ

30
Моя відповідь Крокфорду: Програмування важке, відпускаємо покупки. Sheesh!
Джейсон Джексон

91

Javascript - динамічна мова - це мільйон способів зіпсувати, де інша мова зупинить вас.

Уникнення фундаментальної мовної функції, наприклад, newна основі того, що ви можете зіпсуватись, трохи схоже на те, щоб зняти блискучі нові черевики перед тим, як пройти через мінне поле на випадок, якщо ви можете забруднити взуття.

Я використовую конвенцію, коли назви функцій починаються з малої літери, а "функції", які є фактично визначеннями класів, починаються з верхньої літери. Результат - дійсно досить переконлива візуальна підказка про те, що "синтаксис" неправильний: -

var o = MyClass();  // this is clearly wrong.

На додаток до цього допомагають хороші звички називати. Зрештою, всі функції роблять речі, і тому в його імені повинно бути дієслово, тоді як класи представляють об'єкти і є іменниками та прикметниками без дієслова.

var o = chair() // Executing chair is daft.
var o = createChair() // makes sense.

Цікаво, як забарвлення синтаксису SO інтерпретувало код вище.


8
Так, я думав саме те саме про синтаксичне забарвлення.
BobbyShaftoe

4
Одного разу я забув набрати слово "функція". Слова слід уникати будь-якою ціною. Інший раз я не використовував фігурні дужки у багаторядковому операторі if / then. Тому зараз я не використовую фігурні дужки, а просто пишу однорядкові умовні умови.
Hal50000

"Це явно неправильно" . Чому? Для моїх занять (які просто роблять if (! this instanceof MyClass) return new MyClass()) я фактично віддаю перевагу newсинтаксису -less. Чому? Тому що функції більш загальні, ніж функції конструктора . Якщо вийти з newнього, це легко змінити функцію конструктора на звичайну функцію ... Або навпаки. Додавання newробить код більш конкретним, ніж потрібно. А отже, менш гнучка. Порівняйте з Java, де рекомендується приймати Listзамість того, ArrayListщоб абонент міг вибрати реалізацію.
Штійн де Віт

41

Я новачок у Javascript, тому, можливо, я просто не надто досвідчений у наданні хорошої точки зору на це. І все ж я хочу поділитися своїм поглядом на цю "нову" річ.

Я приїхав із світу C #, де використання ключового слова "new" настільки природно, що для мене дивно виглядає фабрична модель дизайну.

Коли я вперше ввожу код у Javascript, я не розумію, що є "нове" ключове слово та код, як той, що є у шаблоні YUI, і мені не потрібно багато часу, щоб зіткнутися з катастрофою. Я втрачаю інформацію про те, що повинен робити конкретний рядок, оглядаючи код, який я написав. Більш хаотичним є те, що мій розум не може реально переходити межі між об'єктами, коли я пересуваю код.

Потім я знайшов "нове" ключове слово, яке мені "розділяє" речі. За допомогою нового ключового слова він створює речі. Без нового ключового слова я знаю, що не переплутаю його зі створенням речей, якщо функція, на яку я посилаюсь, не дає мені чітких підказок про це.

Наприклад, у var bar=foo();мене немає підказки, як може бути смуга .... Це повернене значення чи це новостворений об'єкт? Але var bar = new foo();я точно знаю, що бар є об'єктом.


3
Погоджено, і я вважаю, що заводський зразок повинен дотримуватися конвенції про іменування, як makeFoo ()
pluckyglen

3
+1 - наявність "нового" дає чіткішу заяву про наміри.
belugabob

4
Ця відповідь є дивним, коли майже все в JS є об'єктом. Чому потрібно точно знати, що функція є об'єктом, коли всі функції є об'єктами?
Джошуа Рамірес

@JoshuaRamirez Справа не в тому typeof new foo() == "object". Це newповертає екземпляр foo, і ви знаєте, що можете дзвонити foo.bar()і foo.bang(). Однак це можна легко пом'якшити, використовуючи @return JsDoc Не те, що я виступаю за процедурний кодекс (уникаючи цього слова new)
Хуан Мендес

1
@JuanMendes Хм ... Твій пост зробив мені здається, що тобі сподобалось нове через чітке ключове слово у кодовій базі. Я можу це копати. Ось чому я використовую схему модуля. У мене буде функція під назвою createFoo або NewFoo або MakeFoo, неважливо, поки це явно. Всередині я декларую змінні, які використовуються як закриття всередині об'єкта-літералу, який повертається з функції. Цей буквальний об'єкт в кінцевому підсумку стає вашим об’єктом, а функція була лише функцією побудови.
Джошуа Рамірес

39

Інший випадок для нового, що я називаю Пух кодування . Вінні-Пух слідкує за животиком. Я кажу, йдіть з мовою, якою ви користуєтесь, а не проти .

Можливо, мовники, які підтримують мову, оптимізують мову для ідіом, які вони намагаються заохотити. Якщо вони додають нове ключове слово до мови, вони, напевно, вважають, що це має сенс бути зрозумілим при створенні нового екземпляра.

Код, написаний відповідно до намірів мови, підвищить ефективність із кожним випуском. І код, уникаючи ключових конструкцій мови, буде страждати з часом.

EDIT: І це виходить далеко за рамки продуктивності. Я не можу порахувати раз я чув (або сказав) : «Чому, чорт візьми , вони робили що ?» при знаходженні дивного вигляду коду. Часто виявляється, що в той час, коли код писався, для цього були якісь «добрі» причини. Слідування мові Дао - це найкраща страховка за те, що не висміювали ваш код через кілька років.


3
+1 для посилання "Кодування Пуха" - тепер мені потрібно знайти виправдання, щоб це
вкласти

ЛОЛ! Я маю багаторічний досвід роботи в цій галузі, і можу запевнити, що ви не знайдете жодних труднощів. На robowiki.net вони часто називають мене Пухом. =)
ПЕЗ

1
Не знаю, чи побачите ви коли-небудь цей коментар, але це посилання на кодування Пуха мертве.
Кальвін

Дякую за голову вгору Ми минулого тижня ми перенесли robowiki.net на нову вікі, і старий вміст наразі недоступний. Я поспішаю з тим, щоб ті старі посилання спрацювали.
ПЕЗ

24

Я написав пост про те, як пом’якшити проблему виклику конструктора без нового ключового слова.
Це здебільшого дидактично, але це показує, як можна створювати конструктори, які працюють з або без, newі не вимагає додавання кодового коду для тестування thisв кожному конструкторі.

http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html

Ось суть техніки:

/**
 * Wraps the passed in constructor so it works with
 * or without the new keyword
 * @param {Function} realCtor The constructor function.
 *    Note that this is going to be wrapped
 *    and should not be used directly 
 */
function ctor(realCtor){
  // This is going to be the actual constructor
  return function wrapperCtor(){
    var obj; // object that will be created
    if (this instanceof wrapperCtor) {
      // Called with new
      obj = this;
    } else {
      // Called without new. Create an empty object of the
      // correct type without running that constructor
      surrogateCtor.prototype = wrapperCtor.prototype;
      obj = new surrogateCtor();
    }
    // Call the real constructor function
    realCtor.apply(obj, arguments);
    return obj;
  }

  function surrogateCtor() {}
}

Ось як його використовувати:

// Create our point constructor
Point = ctor(function(x,y){
  this.x = x;
  this.y = y;
});

// This is good
var pt = new Point(20,30);
// This is OK also
var pt2 = Point(20,30);

6
уникати arguments.callee- це приголомшливо!
Грегг Лінд

2
surrogateConstructorмає бути surrogateCtor(або навпаки).
Девід Конрад

Я підтримував колекцію подібних утилітів, натхнених Крокфордом, і виявив, що мені завжди доводилося працювати, коли я шукаю реалізацію, коли починаю новий проект. І це охоплює таку фундаментальну частину програмування: інстанціювання об'єктів. Все це працює, лише для включення випадкового коду інстанції? Я ціную винахідливість цієї обгортки, чесно, але це, здається, викликає недбале кодування.
Джо Кодер

1
@joecoder Я згадував це лише для дидактичних цілей, я не підписуюся на цей стиль параноя кодування. Однак, якби я писав бібліотеку класів, то так, я би додав цю функцію так, щоб вона була прозорою для абонентів
Хуан Мендес,

22

Обґрунтування невикористання нового ключового слова є простим:

Якщо ви не використовуєте його зовсім, ви уникаєте підводних каменів, які виникають при випадковому його опущенні. Схема побудови, яку використовує YUI, є прикладом того, як можна взагалі уникнути нового ключового слова "

var foo = function () {
    var pub= { };
    return pub;
}
var bar = foo();

Можна також зробити так:

function foo() { }
var bar = new foo();

Але тим самим ви ризикуєте, коли хтось забуде використати нове ключове слово, а цей оператор буде фубаром. AFAIK немає переваги в цьому (крім того, як ви звикли).

На кінець дня: йдеться про захист. Чи можете ви використовувати новий вислів? Так. Чи робить ваш код більш небезпечним? Так.

Якщо ви коли-небудь писали C ++, це схоже на встановлення покажчиків на NULL після їх видалення.


6
Ні. З "new foo ()" деякі властивості встановлюються на поверненому об'єкті, як конструктор.
десь

34
Отже, щоб зрозуміти це: ви не повинні використовувати "нове", тому що ви можете забути його? Ви жартуєте, правда?
Бомбе

16
@Bombe: іншими мовами забуття "нового" призведе до помилки. У Javascript він просто продовжує здійснювати перевірку. Можна забути і ніколи не усвідомити. І просто дивлячись на помилковий код не буде очевидним взагалі, що йде не так.
Кент Фредрік

3
@Greg: Я не бачу, як перша методика дозволяє використовувати прототипові ланцюги - об’єктні літерали чудові, але відкидати продуктивність та інші переваги, надані прототипами з остраху, здається трохи нерозумним.
Shog9

5
@Bombe - Ви повинні використовувати "нове", тому що ви (і той, хто використовує ваш код) ніколи не помилитесь? Ви жартуєте, правда?
Грег Дін

20

Я думаю, що "нове" додає ясності коду. І ясність варта всього. Приємно знати, що існують підводні камені, але уникати їх, уникаючи ясності, для мене не схоже.


16

Випадок 1: newне потрібно і його слід уникати

var str = new String('asd');  // type: object
var str = String('asd');      // type: string

var num = new Number(12);     // type: object
var num = Number(12);         // type: number

Випадок 2: newнеобхідний, інакше ви отримаєте помилку

new Date().getFullYear();     // correct, returns the current year, i.e. 2010
Date().getFullYear();         // invalid, returns an error

5
Слід зазначити, що у випадку 1 виклик конструктора як функції має сенс лише у тому випадку, якщо ви маєте намір перетворити тип (і не знаєте, чи має об'єкт корпусу такий метод перетворення, як toString()). У всіх інших випадках використовуйте літерали. Не String('asd') , а просто 'asd', і не Number(12) , а просто 12.
PointedEars

1
@PointedEars Одним винятком із цього правила буде Array: Array(5).fill(0) очевидно, читабельніше ніж [undefined, undefined, undefined, undefined, undefined].fill(0)і(var arr = []).length = 5; arr.fill(0);
yyny

@YoYoYonnY Моя заява була зроблена в контексті випадку 1 відповіді, який стосується використання newконструкторів для типів об'єктів, що відповідають примітивним типам. Буквал, який ви пропонуєте, не еквівалентний Arrayвиклику (спробуйте 0 in …), а решта - синтаксична помилка :) В іншому випадку ви правильні, хоча це також слід зазначити, що Array(5)може бути неоднозначним, якщо ви вважаєте, що невідповідні реалізації. тому емуляція Array.prototype.fill(…) ).
PointedEars

12

Ось найкоротший підсумок, який я міг би зробити з двох найсильніших аргументів за і проти використання newоператора:

Аргумент проти new

  1. Функції, призначені для інстанції як об'єкти, що використовують newоператора, можуть мати катастрофічні наслідки, якщо їх неправильно викликати як звичайні функції. Код функції в такому випадку буде виконуватися в області, де викликається функція, а не в області локального об'єкта за призначенням. Це може спричинити перезапис глобальних змінних та властивостей із згубними наслідками.
  2. Нарешті, написання function Func(), а потім виклик Func.prototype та додавання до нього матеріалів, щоб можна було зателефонувати, new Func()щоб сконструювати ваш об'єкт, виглядає негарним для деяких програмістів, які скоріше використовуватимуть інший стиль успадкування об'єктів з архітектурних та стилістичних причин.

Детальніше про цей аргумент див. У великій і стислій книзі Дугласа Крокфорда Javascript: Хороші частини. Насправді перевірити це все одно.

Аргумент на користь new

  1. Використання newоператора разом із призначенням прототипів швидко.
  2. Цей матеріал про випадкове виконання коду функції конструктора в глобальній просторі імен легко запобігти, якщо ви завжди включаєте трохи коду в функції конструктора, щоб перевірити, чи правильно вони викликаються, і в тих випадках, коли вони відсутні , належним чином обробляючи дзвінок.

Див . Пост Джона Ресіга про просте пояснення цієї методики та загалом глибше пояснення моделі успадкування, яку він відстоює.


Оновлення аргументів проти: №1 можна пом'якшити за допомогою 'use strict';режиму (або методу за вашим посиланням) №2 Має синатичний цукор у ES6 , проте поведінка така ж, як і раніше.
ninMonkey

9

Я згоден з pez і деякими тут.

Мені здається очевидним, що «нове» - це самоописанне створення об'єктів, де шаблон YUI, який описує Грег Дін, повністю затьмарений .

Можливість, щоб хтось міг написати var bar = foo;або var bar = baz();де baz не є методом створення об'єктів, здається набагато небезпечнішим.


8

Я думаю, що нове - це зло не тому, що якщо ви забудете використовувати його помилково, це може спричинити проблеми, а тому, що воно накручує ланцюжок спадкування, роблячи мову більш жорсткою для розуміння.

JavaScript орієнтований на прототип, об'єктно-орієнтований. Отже, кожен об’єкт ОБОВ'ЯЗКОВО повинен бути створений з іншого об'єкта, як це var newObj=Object.create(oldObj). Тут oldObj називається прототипом newObj (отже, "заснований на прототипі"). Це означає, що якщо властивість не буде знайдено в newObj, вона буде шукана в oldObj . Таким чином, newObj за замовчуванням буде порожнім об'єктом, але завдяки ланцюгу прототипу, схоже, є всі значення oldObj .

З іншого боку, якщо це зробити var newObj=new oldObj(), прототип newObj є oldObj.prototype , який неможливо зрозуміти.

Хитрість полягає у використанні

Object.create=function(proto){
  var F = function(){};
  F.prototype = proto;
  var instance = new F();
  return instance;
};

Саме всередині цієї функції і тільки тут слід використовувати нове. Після цього просто використовуйте метод Object.create () . Метод вирішує проблему прототипу.


7
Якщо чесно, я не дикий щодо цієї методики - вона не додає нічого нового, і, як показує ваша відповідь, вона навіть може бути милістю. IMHO, розуміння ланцюжків прототипів та інстанції об'єктів має вирішальне значення для розуміння JavaScript ... Але якщо вам незручно безпосередньо ними користуватися, то добре використовувати функцію помічника для догляду за деякими деталями, доки ви пам’ятаєте, що ви робити. FWIW: (дещо корисніший варіант) щодо цього є частиною ECMAScript 5-го видання. std, і вже доступний у деяких браузерах - тому слід бути обережним, щоб не сліпо переробити це!
Shog9

BTW: Я не впевнений, чому ви зробили цей CW, але якщо ви хочете повторно опублікувати його з внесеними вами корекціями форматування, будьте обережні, щоб уникнути цього прапорець ...
Shog9

2
Не зайве важко зрозуміти? var c = new Car()те саме, що робитиvar c = Object.create(Car.prototype); Car.call(c)
Хуан Мендес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.