Pull to refresh

Comments 50

Напишу на джаваскрипте машину времени и отправлю эту статью себе в 2005 год!

Меня в 2007 сильно выручил javascript.ru, хабр. и гугл, который вывел меня на нужные статьи.

А меня в 2005 — PPK и наблы. Но я больше про то, что сейчас такие статьи смотрятся как-то… запоздавше, что ли.
Сейчас все про это пишут. А я года до 2008 не слышал словосочетания «объект активации», например.

Свежо, но нынче есть ES6 и собственно словосочетание JavaScript теряет контекст о какой версии мы говорим.

Да тащем-та прототипы и в ES6 никуда не делись. Хотя, конечно, городить костыли для наследования классов уже не надо.

Древнее зло пробудилось. Дальше будет статья про jQuery?

Нет, я не против статей для новичков, но почему бы не учить актуальным (не модным, а актуальным) вещам? А не всяким __proto__:
Warning: While Object.prototype.__proto__ is supported today in most browsers, its existence and exact behavior has only been standardized in the ECMAScript 6 specification as a legacy feature to ensure compatibility for web browsers. For better support, it is recommended that only Object.getPrototypeOf() be used instead.


Добавить бы в статью новшеств, которые облегчают жизнь (https://learn.javascript.ru/es-modern) и было бы… точно также как у всех.
Не холивара ради, но меня интересует третья строчка в функции extend:
    function extend(Child, Parent) {
           var F = function() { }
           F.prototype = Parent.prototype // 
           Child.prototype = new F() // при создании Child в __proto__ запишется наш родитель prototype 
           Child.prototype.constructor = Child // задаём конструктор, должен ссылаться на самого себя.
           Child.superclass = Parent.prototype // чтобы иметь доступ к методам Parent
    };


Чем Вам не угодил Object.create?
Вопрос снят. Оказывается в IE8- Object.Create нет.

Ага, это то, как полифиллится Object.create, если его где-то нету.

Чтобы совсем исправиться за глупый вопрос, добавлю, что на MDN есть супер-продвинутый пример полифила Object.create по сравнению с канторовским, который упомянул wentout, и который использовал автор.

Полифил
if (typeof Object.create != 'function') {
  // Production steps of ECMA-262, Edition 5, 15.2.3.5
  // Reference: http://es5.github.io/#x15.2.3.5
  Object.create = (function() {
    // To save on memory, use a shared constructor
    function Temp() {}

    // make a safe reference to Object.prototype.hasOwnProperty
    var hasOwn = Object.prototype.hasOwnProperty;

    return function (O) {
      // 1. If Type(O) is not Object or Null throw a TypeError exception.
      if (typeof O != 'object') {
        throw TypeError('Object prototype may only be an Object or null');
      }

      // 2. Let obj be the result of creating a new object as if by the
      //    expression new Object() where Object is the standard built-in
      //    constructor with that name
      // 3. Set the [[Prototype]] internal property of obj to O.
      Temp.prototype = O;
      var obj = new Temp();
      Temp.prototype = null; // Let's not keep a stray reference to O...

      // 4. If the argument Properties is present and not undefined, add
      //    own properties to obj as if by calling the standard built-in
      //    function Object.defineProperties with arguments obj and
      //    Properties.
      if (arguments.length > 1) {
        // Object.defineProperties does ToObject on its first argument.
        var Properties = Object(arguments[1]);
        for (var prop in Properties) {
          if (hasOwn.call(Properties, prop)) {
            obj[prop] = Properties[prop];
          }
        }
      }

      // 5. Return obj
      return obj;
    };
  })();
}

А в полифиле-то ошибка! Второй аргумент содержит дескрипторы свойств, а не значения, поэтому присваивать obj[prop] = Properties[prop]; некорректно

По-видимому, Вы правы. Результаты совсем не идентичными получаются.
jsFiddle
Вместо значения свойства переносится его дескриптор. По-видимому надо вызывать в этом месте Object.defineProperties… для которого тоже нужен будет полифил=)

Если посмотреть на английскую версию в MDN — то там полифил вообще без второго параметра. Видимо, переводчики отсебятину добавили...

Привет.

У Вас там где «Четыре варианта вызова и его результаты:»…
Там для:

Constructor: new func(args) – this == new object


Это, конечно, новый объект, но он всё же обладает свойствами и методами прототипа func.prototype.
Т.е., для this внутри конструктора скалярные свойства будут свои, а методы будут те, что у func.prototype.

Соответственно, поэтому фраза:
prototype нужен только для того, чтобы сказать, что нужно записать в __proto__ при инстанцировании нового объекта.

не совсем корректна, т.к. даже через конструктор с прототипом можно наделать кучу сайд-эффектов.

На гипотетический пример, в прототипе можно изменить какое-нибудь свойство через его конструктор, и это отразится на всех наследниках.
Автор, пожалуйста, пощадите новичков и повесьте дисклаймер c предупреждением, что перечисленные в статье методы уже как пару лет устарели.
С чего бы они устарели? Я аккурат сегодня столкнулся с IE8 и необходимостью поправить функцию, при разработке которой забыли, что мы его поддерживаем…
Ну вы же сами сейчас привели в пример поддержку легаси браузера. Потому и устарели.
Сейчас новичкам (а это статья именно для них) рекомендовал бы в первую очередь учиться писать адекватный es6 код, пользоваться экосистемой и следить за новостями, а не учиться поддерживать легаси, которое отвалится раньше, чем они освоятся в веб разработке.
> поддерживать легаси, которое отвалится раньше, чем они освоятся в веб разработке.
Как бы не так. Черти мелкомягкие всех нас переживут.
А в веб-разработке нужно постоянно помнить о легаси, потому что то, о чём пишут в новостях, внедряется долго и мучительно.
Проблемы частично решаемы, в стилях — автопрефиксерами, в коде — транспайлерами, но все же с легаси лучше не связываться, себе дороже.
Кстати отказ совместимости со старыми браузерами уже давно вошел в тренд, вполне возможно что автообновление браузеров утопит IE8 куда быстрее чем мы думаем.
отказ совместимости со старыми браузерами уже давно вошел в тренд

Вы это РЖД расскажите. И подобным же большим и неповоротливым организациям, которые 15 лет на ворованной ХР просидели отключив автообновление, и ещё столько же просидят.
А они, между прочим, наиболее жирные из клиентов.

Наверное вы правы, но это решение разработчика, с чем связываться, а с чем нет. На рынке достаточно проектов, где про существование IE8 можно забыть, правда это большей частью фронтендерские вакансии, что стоит признать.
Если новичкам не рассказывать про прототипы, то они даже знать этого не будут. И будут говорить, что в JS есть классы. А что это на самом деле, как работает — это уже не важно. В итоге имеем ребят, которые не знают инструмента, которым пользуются.
А по поводу статьи, я бы просто порекомендовал Шаблоны проектирования Больше и подробнее.

Я думаю, имелись в виду не прототипы, а хитрая магия с одноразовым конструктором вместо Object.create
В принципе, сейчас, наверно, уже не столь важно знать, как работает полифил.

Про протитипы знать несомненно надо, но точно не в контексте «собираем на коленке очередную систему прототипного наследования». Пример адекватной на мой взгляд подачи материала для новичков — https://learn.javascript.ru/, где легаси подходы честно помечены и подаются в последнюю очередь и с соответствующим предупреждением.

Посмотел вашу книжку, простите, она никуда не годится. Там есть замечательная глава «заимствование конструктора» с примерно таким содержанием:
function StaticPage() {
Article.call(this);
}

Шел 2016 год…
Во-первых, есть несколько изданий этой книги разных лет. Я привел 2011, кажется. Во-вторых, иметь знания о том, как можно сделать и принимать решение уже исходя из задачи — вот что должен уметь хороший инженер. Статье, возможно, не хватает информации о том, какие надстройки появились в языке, чтобы не писать столько кода самому, но говорить, что значит этого не надо — это точно неправильно. Да и какая разница, 2016 или 2116 год, если в основе языка это лежит, то знать это надо. А еще надо знать какие возможности есть и как ими пользоваться.
Тут критерий намного проще и он никак не связан с «инженерами». В современном проекте с мощной фронтенд частью такой код, особенно от начинающего разработчика (а статья именно для них) просто неприемлем, он элементарно не пройдет ревью. Следовательно читать такой код нужно только для расширения кругозора, но никак не в качестве production ready варианта.

В качестве аналогии приведу php4, можно развешивать на харбре гайды об эмуляции ооп и паттернах процедурного программирования, а можно давать актуальную на данный момент информацию по php5\7 и делать мир лучше.
Никакие «тыжеинженер» «этооснова» не оправдывают такого порядка подачи материала. Это просто глупо и нерационально.

Книжка правда хорошая, но приведенное издание (не знаю, есть ли посвежее) безнадежно устарело. Про Article.call(this); знать надо, но только для того, чтобы не падать в обморок над легаси-кодом.

Они устарели с рождения. Ни new, ни тем более this в ООП коде на javascript лучше не использовать.


Лучше писать код типа


var Thing = function() {
    var that = {};
    that.publicNumber = 4;

    var privateNumber = 5;

    that.getPrivateNumber = function() {
        return privateNumber;
    }

    return that
}

var thingInstance = Thing();

Не успел поправить пост.
Есть мнение, что


Определять методы внутри функции конструктора, это антипатер приводящий к лишнему расходу памяти

А острая тоску по приватным свойствам — тем более не понятна, если не хочешь обращаться к свойству из других объектов — не обращайся к нему, и не надо городить велосипеды.

Если такой объект создается часто, то да. Если он создался один раз и дальше вся работа с уже созданным — то особой разницы нет

На счет this и new тоже не понял почему так, так как с приходом es6 классов снова используется и this и new

Если он создаётся один раз, то почему его просто не о объявить, безо всяких фукнций-обёрток?


снова используется и this и new

А они никуда и не девались. Наследование на прототипах разве что не так лаконично, как объявление классов, но в целом не менее удобно.

Вообще это рекомендации Дугласа Крокфорда такие. this плохо, потому что он контекстозависим, new плохо потому, что даёт возможность одному и тому же коду (функции) работать по разному. Обращаться к свойствам объектов можешь не только ты, но и какой-нибудь вредоносный код. Лучше не давать ему возможности это делать.


Что касается излишнего расхода памяти — сборщик мусора уберёт всё. А если у вас много долгоживущих объектов, то, может быть какие-то пролемы и будут. Но их очень много должно быть.

this плохо, потому что он контекстозависим,

Что в этом плохого?


new плохо потому, что даёт возможность одному и тому же коду (функции) работать по разному.

Что в этом плохого?


Обращаться к свойствам объектов можешь не только ты, но и какой-нибудь вредоносный код.

Какой к аллаху вредоносный код на клиентской стороне?


Что касается излишнего расхода памяти — сборщик мусора уберёт всё

И что же он сделает с копиями методов в каждом объекте?

Какие у вас странные кавычки в коде

Сберегу время тех, кто тоже пойдет по этой ссылке и приведу цитату, после которой можно не читать:


Try adding .1 + .2 in your browser console, for instance. I still think Brendan Eich
все любители обмазыватся ООП в JS давно уже открыли для себя
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes
или дауншифтнулись на TypeScript

чего и вам советую.

А потом приходит страшный IE8

куда приходит?

https://habrahabr.ru/post/274595/
Microsoft прекращает поддержку всех версий IE, кроме 11

и то было уже в январе

все адекватные ведущие компании анонсировали прекращение поддержки старых версий в своих продуктах

— секюрити патчи вы надеюсь тоже накладываете на старые версии.
а то как то не хорошо дырявый софт клиенту продолжать впаривать.
тот же Bitrix например

А РЖД — не прекращает. И все 200 000 человек не пересядут с мелкомягкой мерзости на браузеры из-за того, что разработчику веб-приложения так удобно. Они скорее разработчика сменят.
То же касается туевой хучи российских компаний на огромную сумму общей стоимости заказов.

РЖД — это конечно двигатель интернета и куча никому не известных российских компаний.
пусть сидят чо. до первых прецедентов взлома и получения убытков.
сами себе яму копают продолжая заявлять что поддержкивают устаревший софт который даже не они разрабатывают и не могут на него никак влиять.

Взломают их или нет, это на 100% их трудности. Но терять такого мощного клиента как они — дураков нет.

куда приходит?

https://habrahabr.ru/post/274595/
Microsoft прекращает поддержку всех версий IE, кроме 11

и то было уже в январе

все адекватные ведущие компании анонсировали прекращение поддержки старых версий в своих продуктах
тот же Bitrix например.

и секюрити патчи вы надеюсь тоже накладываете на старые версии.
а то как то не хорошо дырявый софт клиенту продолжать впаривать.
Аляповатая статья. Много неточностей и ошибок.

Понять это сможет только тот кто уже достаточно хорошо знаком с темой прототипного наследования, замыканий, конструкторов, подмены контекстов.., а новички не поймут из-за логических ошибок в тексте, неточностей и иногда лени автора в разжевывании темы.

А тка-же всем придётся нехило повтыкать в примеры, например чтобы понять что [args] это не массив с одним членом а просто массив)
UFO just landed and posted this here
Sign up to leave a comment.