Comments 87
Готовлюсь к собеседованию — и в планах было выделить сегодняшний день на ES2015. А тут ты с переводом. Как знал! как знал.
P.S. Для собеседования детали лучше посмотреть в учебнике Ильи Кантора, там больше подробностей.
В ECMAScript 3/5 это поведение стало возможным изменить, присвоив значение this другой переменной.
Вы видимо про Function.prototype.bind не слышали?
До сих пор полной поддержки ES6 нет ни в одном стабильном браузере, а если брать в расчёт до сих пор живые IE… вот только ES6 используется чуть менее, чем повсеместно. Function#bind
достаточно хорошо, хоть и не полностью, полифилится, чем все с самого начала и пользовались. Так что-что, а поддержка браузерами, в отличии от спецификации, в данном контексте, как вы выразились, "совершенно минорна".
Здесь есть два момента:
1. Это перевод, в котором не было написано про bind
2. Насколько я понимаю, суть текста верна — для решения проблемы можно использовать приём с var self = this.
В связи с перечисленными двумя пунктами, в чём конкретно у вас претензия к тексту? В отстутствии упоминания про Function.prototype.bind?
Думаю, что можно создать PR автору, он достаточно оперативно их рассматривает (мой PR рассмотрел в тот же день).
В любом случае спасибо за полезный комментарий.
Я бы предположил «остаток» или, по созвучию, «хвост» — использование rest-оператора в качестве единственного агрумента функции — это вырожденный случай, в общем виде это что-то вроде
function(a, b, c, ...moreArgs) {...}
Т.е. оператор возвращает в виде массива оставшиеся неописанными аргументы.
1. Не работают ссылки на разделы (а код страницы показывает отсутствие якорей в заголовках).
2. В начале раздела про шаблоны странное:
\${… }`` — зачем-то экранирование и ${… } вынесено за кавычки
``` — зачем-то тройные кавычки
Аналогично. У них в коде как раз id и name, но в моей публикации это почему-то не работает.
Вчера минут 40 потратил на то, чтобы попробовать различные варианты, но все не работали.
Простите, что не исправил. Буду разбираться дальше, а то непорядок.
P.S. Какое совпадение, я тоже ориентировался на дайджест фронтенд-разработки)
Как и раньше — никак.
Используйте TS, либо извращайтесь через Symbol
'ы.
Согласно философии JavaScript: если не хотите обращаться к членам объекта из других объектов — не обращайтесь к ним.
- Использовать конвенцию, префиксуя приватные члены класса символом нижнего подчеркивания
- Обернуть всё в функцию, используя ее локальные переменные для хранения приватных данных (с помощью замыканий)
Стоит заметить, что TS ограничивает доступ к приватным переменным только на уровне проверки типов. Они все равно будут доступны из кода на чистом JS, или при приведении объекта к типу
any
.Классовое наследование — это хороший синтаксический сахар. Одна строчка вместо трёх.
Лично мне не нравится, что системную переменную super ввели только для классов. Общая идея JavaScript предполагает, что раз есть системная переменная, то она всегда должна быть чему-то равна. Как это сделано для this.
Вы, кстати, писали когда-нибудь объёмное приложение на JavaScript? Я с не вижу в этом особой головной боли. А препроцессоры считаю ересью.
С IDE вообще беда — ни одна среда пока что не может нормально обработать класс и отобразить что то адекватное в автокомплите. После долгих переборов IDE остановился пока что на VisualStudio. Там какой то хитрый автокомплит, что походу дела среда запускает некоторые куски кода, и получаем более адекватные подсказки при написании кода. Остальные же редакторы заточены под определенный стиль.
Справедливости для: приватные члены — просто соглашение. В тех же плюсах его нарушить достаточно просто. В js вы можете для этого использовать либо Symbol, либо по-старинке через нижнее подчёркивание, причём и то и другие — тоже соглашение и тоже запросто нарушается. Ну либо можно всё через замыкания и/или WeakMap делать, но получится страшно.
Кстати, иногда неплохо затрудняет отладку какого-нибудь обфусцированного кода, когда, к примеру, нужно вызвать напрямую какой-нибудь «приватный» метод.
function test(){
var innerFunction=function(){
console.log("You can't call me outside");
};
this.outer=function(){
console.log("You can call me, but for what?");
};
setTimeout(innerFunction, 1000);
}
Сферический пример в вакууме.
innerFunction вызовется 1 раз и нанай. А если для отладки нужно ее запустить раз 5. к примеру? Ну или не отладки. а каких-нибудь личных хитровымудренных нужд(к примеру. для автоматизации каких-либо процессов на сайте при помощи userscri[t'ов).
Еще полезное применение деструктуризации аргументов функции:
function userId({id}) {
return id;
}
let user = {id: 1}
userId(user)
let arr = ['apple', 'banana', 'orange'];
let breakfast = arr.map(fruit => fruit + 's');
alert(breakfast);
При использовании const
рекомендуется использовать ПРОПИСНЫЕ_БУКВЫ.
Кем рекомендуется? Укажите ссылку, пожалуйста.
let nicknames = ['di', 'boo', 'punkeye']; nicknames.size = 3; for (let nickname of nicknames) { console.log(nickname); }
По-хорошему, стоит использовать const
для всех переменных, которые не планируется переприсваивать:
const nicknames = ['di', 'boo', 'punkeye'];
nicknames.size = 3;
for (const nickname of nicknames) {
console.log(nickname);
}
Функции, записанные с помощью ключевого слова static
, используются для объявления статических свойств класса.
Пока что только только методов. Более общие свойства — в stage-1.
А, извините, это перевод. Надо будет задать эти вопросы в оригинальный репозиторий, если не забуду.
Upd: по крайней мере последний вопрос — к переводу, в оригинале:
Functions defined using the static keyword implement static/class functions on the class.
Спасибо за комментарии.
По поводу прописных букв написано на сайте MDN в части с примерами, если переводить дословно — "использование всех прописных букв является общим соглашением".
"Common convention is to use all-uppercase letters"
Документация с сайта MDN работает по принципу вики, и хотя в целом она адекватна, там есть весьма спорные вещи. Не следует ей всегда слепо верить.
За ссылку спасибо. =)
Конкретно эту правку внёс https://github.com/agutoli, и это был его единственный вклад в MDN.
Оттуда она и перекочевала в ваш документ.
На самом деле общепринятая практика — это eslint c prefer-const, с которым в коде почти все переменные будут const
. И прописными буквами их все никто не называет.
Спасибо большое! Не знал насчёт документации MDN.
Ну как бы прописные для констант имхо со времен С идет. Вы потом в коде как определять будете что это константа и в нее писать не надо? Держать в голове? Зачем?
Дело в том, что в коде на яваскрипте большая часть переменных — фактически константы (не переприсваиваются). Вы предлагаете всё именовать большими буквами?
Мне нравится подход, описанный на сайте learn.javascript.ru:
Константы, которые жёстко заданы всегда, во время всей программы, обычно пишутся в верхнем регистре. Например: const ORANGE = "#ffa500".
Большинство переменных – константы в другом смысле: они не меняются после присвоения. Но при разных запусках функции это значение может быть разным. Для таких переменных можно использовать const и обычные строчные буквы в имени.
Нет конечно (хотя про большую часть я бы поспорил). Но переменная, которая не переприсваивается — это не константа. Она не переприсваивается в силу алгоритма работы и при смене алгоритма может быть изменена. Константа — не переприсваивается в силу алгоритма и при доработках — надо иметь в виду что изначально в нее не планировалось ничего писать — не потому что так вышло при реализации а потому что так изначально планировалось. И этот момент неплохо бы видеть при внесении правок. Поэтому данные из конфига — обычно в верхнем регистре. А временные переменные, рабочие лошадки — в нижнем. Но это соглашение, не более того. Оно придумано для облегчения жизни, и если его соблюдение лично Вам жизнь не облегчает — нет смысла его придерживаться.
Нет конечно (хотя про большую часть я бы поспорил).
Зашёл в первый попавшийся проект, посчитал — 90.6% const
, 9.4% let
. Общую статистику по всем подводить как-то не хочется, но если хотите — посчитайте =). Но в таком проекте, где с var
слезли уже.
Всё, что вы дальше говорите — к const
не имеет отношения. Дело как раз в том, что const
— это не то же самое множество, что константы, которые именуются большими буквами. Те могут быть как var
в ES5, так и вообще свойствами какого-то объекта вроде MyLib.CONSTANT_NAME
. А const
как раз используется для тех переменных, которые не собираются переприсваивать, и говорить «для переменных const
названия пишите в верхнем регистре» — глупость несусветная.
Пример:
for (const name of names) {
…
}
Тут я точно знаю с первого взляда на код, что name
внутри блока — всегда один и тот же и не изменяется волшебным алгоритмом. Я его что, дожен NAME
назвать?
и говорить «для переменных const названия пишите в верхнем регистре» — глупость несусветная.
А кто такое сказал?
Я его что, дожен NAME назвать?
Нет, Вы мне ничего не должны. Я Вам тоже.
А кто такое сказал?
Да в статье ж русским по белому написано:
При использовании const
рекомендуется использовать ПРОПИСНЫЕ_БУКВЫ.
При использовании const рекомендуется
и говорить «для переменных const названия пишите в верхнем регистре»
разницу видите? Вы сами придумали глупость и сами ее глупостью назвали.
[зануда-моуд]
Хорошо. Рекомендовать использовать прописные буквы для именования всех без разбора const
-переменных — глупость.
[/зануда-моуд]
Так лучше?
Вы рано зануду выключили, я только прогреваться стал )
Рекомендация — то же, что совет, пожелание или предписание, высказанное в необязательной форме
С вики конечно, но сути не меняет.
Необязательная форма подразумевает нестрогое исполнение, то есть по сути — по обстоятельствам. А никак не всех без разбора. Поэтому есть рекомендации, есть стандарты, в стандартах не просто так расписывают в начале should, must, may.
Да, но только отношение const
к константам, которые действительно стоит именовать заглавными буквами — примерно как между тапками и красным. Тапки бывают красные, бывают не красные. Красные бывают тапки, бывают не тапки.
Так стоит ли в статье-инструкции по рукоделию для новичков включать пункт «тапки красьте в красный цвет»?
Тапки бывают красные, бывают не красные. Красные бывают тапки, бывают не тапки.
Какая классная фраза!
А по теме, тоже придерживаюсь именования заглавными констант уровня модуля, а «на месте» — строчными.
Новички — это будущие профессионалы и не надо к ним относиться как к бабочкам. Есть краска, есть тапки, есть кисточка. Они могут красить тапки в красный цвет, могут не красить. А могут и не тапки. Могут не кисточкой. Могут забить на программирование и пойти красить заборы — тоже польза.
Я не разработчик на JavaScript, но языки программирования вообще — мой интерес, и поэтому я сталкивался с этой концепцией где-то еще… но так и не понял в чем фишка.
А вообще очень приятные фичи, рад за JavaScript.
{ x: 1 }
. Поскольку строки сравниваются по значению, любой, кто в состоянии написать букву x
, будет иметь доступ к этому свойству объекта.С другой стороны, каждый
Symbol
является уникальным:var a = Symbol("a");
var b = Symbol("a");
console.log(a === a); // true
console.log(a === b); // false
У
Symbol
есть еще две особенности. Во-первых, его можно (и нужно!) использовать в качестве ключа объекта. Кроме него ключами могут быть только числа и строки, никакие другие объекты использовать нельзя. Во-вторых, при перечислении содержимого объекта (for(var x in obj) ...
) свойства с символьными ключами не указываются.Таким образом, можно создать уникальный идентификатор свойства и сохранить его в локальную переменную. Свойство будет содержаться в объекте, но обратиться к нему можно будет только если есть доступ к этому идентификатору. Получаются «почти что» приватные поля:
function createPerson(age) {
var agePty = Symbol("age");
var person = { };
person[agePty] = age; // обращение по уникальному Symbol
person.getAge = function() { return person[agePty]; };
person.birthday = function() { person[agePty]++; };
return person; // agePty больше не видна
}
var me = createPerson(21);
person.getAge(); // 21
person.birthday();
person.getAge(); // 22
me["age"]; // undefined - недоступно
me[Symbol("age")]; // также недоступно
Я говорю «почти» приватные, потому что список символов в объекте всё равно можно получить через специальный API.
Ну и, опять же, каждый символ уникален, даже с одним и тем же описанием. Это дает гарантии на уникальность полей.
Мне, например, приглянулся способ «наладить общение» между декораторами в библиотеке, когда у одного из них есть доступ к символу другого, чтобы скорректировать по наличию этого символа на прототипе свою работу.
Небольшой хинт — spread еще весьма удобно использовать для фокусов в стиле пуша массива в массив:
var a=[1,2,3];
var b=[4,5];
a.push(...b); //a==[1,2,3,4,5];
a = a.concat(b);
Кроме того у push`a есть ограничение на количество аргументов (для FF 47 — 5e5, для Ya 16 — 2.5e5).
Да и работает concat куда быстрее — jsfiddle
p.s. «a.push.apply(a, b)» работает быстрее, чем concat.
P.S. spread работает не с массиводоподобными, а с итерируемыми объектами! Т. е. если просто создадите объект с числовой последовательность в качестве ствойств и свойство «length», то spread работать не будет ( Exception: TypeError: obj is not iterable ).
ES6 по-человечески