Pull to refresh

Comments 29

Спасибо за перевод.

По-поводу Symbol: есть заранее определенные стандартные символы, которые позволяют настроить поведение объекта. Самое интересное, наверное, это возможность создания пользовательского for..of итератора через Symbol.iterator. MDN.
console.log(product.type = «orange»); //logs «orange»
«Геттер не выполняется в то время как возвращается устанавливаемое значение»

Это правильное поведение, что бы можно было писать вот так:
var fruit;
fruit = product.type = «orange»;
моя встроенная сигнализация плохого JavaScript до сих пор срабатывает, когда я вижу прямое обращение и задание свойств экземплярам объекта. За долгое время я был научен багами и техническими требованиями избегать произвольного задания свойств экземплярам класса, так как это непременно приводит к тому, что информация распространяется между ими всеми.

Киньте, пожалуйста, ссылкой, где можно прочитать подробнее про это «распространение». Ну или объясните на пальцах :-)
А чего вы ожидаете, если меняете прототип конструктора, который по сути является набором статический свойств, общих для всех экземпляров. Тут вам и get/set не поможет. Используя _.extend вы создаете объект, но свойство prop1 копируется в него по ссылке.

Чтобы избежать этого поведения вам нужно выносить prop1 из прототипа или использовать deep copy
Пример
valueOf и toString везде и всегда.

Object.create, Object.keys — IE9+, в старых легко реализуется полноценный полифил.

Геттеры и сеттеры в литерале объекта, Object.defineProperty, Object.defineProperties, Object.preventExtensions, Object.seal, Object.freeze, Object.getOwnPropertyNames — IE9+, полноценный полифил невозможен.

Symbol — Chrome 38 (с 35, если не ошибаюсь — с флажком экспериментальных возможностей), FF33, обещают в IE12. Полноценный полифил невозможен, частичная реализация функционала — вполне.

Proxy давно доступен в стабильном FF. В v8, по крайней мере, до недавних пор — с флажком экспериментальных возможностей, но в нём устаревшая версия, чьё api можно подогнать под актуальное. Сейчас не вижу. Полифил на базе ES5 невозможен.
Object.create() полноценно полифилить не получится, если поддерживать второй параметр propertiesObject.
Ну это само собой, задача объявления свойств перекладывается на Object.defineProperties — не вдаваться же в такие подробности, а то не комментарий, а статья получится. Зато с первым параметром, включая null, всё полифилится, хоть и через опу.
product.type = «apple»;
гораздо более читаемо, чем:
product.setType(«apple»);

Горите в аду, те кто так будет делать.
Я понимаю ещё в типизированных языках так можно писать, где легко перейти к определению get/set.
Но в js, читая чужой код или вспоминая свой, найти определение или понять поле это или settter

product.type = «apple»;

просто нереально.

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


Абсолютной правильной архитектуры как и программы не бывает.
Ну, это в теории, а на практике багов и непоняток хватает и так, особенно в незнакомом коде.
Я чтото не могу уловить принципиальную разницу между Symbol и String.
Разница только в том, что Symbol нельзя изменить? Это все?
Если совсем принципиально, символы были придуманы, когда строки были изменяемыми in-place списками char'ов. Можно считать, что джаваскриптовые строки выполняют роль символов в случаях, когда вы не проводите с этими строками никаких строковых операций.
И один, и другой тип данных могут использоваться в качестве ключей. Первоначально Symbol должен был называться Name и предназначался для создания ключей приватных свойств объекта. Каждый вызов Symbol возвращает уникальный ключ, символы не участвуют в обходе через for-in, что должно было сделать данные, расположенные по ключам-символам, полностью приватными. Однако, приватность слегка ослабили, для получения собственных символов объекта добавили метод Object.getOwnPropertySymbols.
Мда, тогда они использовали для него не очень хорошее название, проводящее аналогию между символьными типами в других языках, тогда как на самом деле никакой аналогии нет =( Лучше бы назвали его в духе UniqueID или вроде того
Я думаю, что разработчики вдохновлялись классом Symbol из Ruby. А авторы Rubby взяли эту сущность из старого доброго Smalltalk. Для разработчиков на этих языках термин Symbol уже привычен. Думаю, что и в JS он приживётся.
да, но что в ruby, что в smalltalk symbol == symbol, тогда как в js нет
Пример:

var Person = (function(){
  var NAME = Symbol('name');
  function Person(name){
    this[NAME] = name;
  }
  Person.prototype.getName = function(){
    return this[NAME];
  };
  return Person;
})();

var person = new Person('Вася');
console.log(person.getName());          // => 'Вася'
console.log(person['name']);            // => undefined
console.log(person[Symbol('name')]);    // => undefined, каждый вызов Symbol возвращает уникальный ключ
for(var key in person)console.log(key); // => только 'getName', символы не участвуют в обходе объекта
Это то, чего действительно не хватало в JS. Наконец можно будет реализовать по-настоящему приватные свойства.
В Chromium 40 с флажком экспериментальных возможностей работает. Классы, в отличии от нового типа данных — символов, только синтаксический сахар, никто не мешает использовать их уже сейчас, прогоняя код через препроцессор. А без препроцессора на клиенте им всё равно делать нечего ближайшие лет 5 — спасибо IE за политику обновления.
О да, автоматическое обновление браузера — панацея :D 1 версия браузера в 2 года, между версиями нет нововведений. Современные версии IE в старых версиях Windows недоступны. Спасибо мелкомягким за приятную web-разработку!
Only those users with full accounts are able to leave comments. Log in, please.