Вполне может быть, в реализации промисов Bluebird от Petka Antonov, которые быстрее нативных, как раз используется изолированная функция tryCatch для catch, использование которой не мешает V8 оптимизировать весь остальной ваш код
Для теоретического async-await пока вариант явно отказаться либо от ловли ошибок, либо от оптимизаций (интересно как с этим дела в Edge). Может потому и не спешат внедрять
Кстати, в V8 уже оптимизировали некоторые моменты из числа убийц:
функции, содержащие выражение for-of;
функции, содержащие составной оператор присваивания let;
функции, содержащие составной оператор присваивания const;
функции, содержащие объектные литералы, которые, в свою очередь, содержат объявления __proto__, get или set.
бесконечные циклы
5.1. Ключ не является локальной переменной (первый пример с nonLocalKey1)
частично 5.2. Итерируемый объект не является «простым перечисляемым»
может что-то еще, протестировал только эти
Function is optimized by TurboFan
И вполне возможно скоро можно будет не так активно задумываться над убийцами оптимизаций
Спасибо за инструкцию как запускать проверку в браузере
Вот еще до кучи вариант со стрелочными функциями (которые, как известно, дешевле и быстрее создаются и вызываются, и вовсе не имеют arguments):
var testFunction = (...args) => {
let a = Array.from(args);
args = 4;
return a;
}
Результат:
Function is optimized by TurboFan
После работы бабеля получается тоже оптимизированная функция:
Function is optimized
Проверил так же различные варианты стрелочных функций (в том числе и в прототипах), они всегда оптимизировались (по крайней мере не удалось найти вариант, чтобы оптимизации не было)
Если есть желание, можно проверить еще и на 6.0.0 ноде, где более актуальная версия v8 4.9.385.27 (chrome ~49), против 4.6.85.31 (chrome ~45) в node 5.10.1 (в 5 ветке вообще v8 не менялся с 5.1.0)
Ночные сборки 6.0.0 ноды: https://nodejs.org/download/nightly/
1. здесь нечего оптимизировать, код инлайнится в простой return args, так как ...args в отличии от arguments просто массив
2. теперь и вы убедились, что ваш совет и вывод про статью были ошибочны
3-5. Невозможно просто заинлайнить, оптимизируется как и ожидалось
Итого. Используйте es6 + babel и никого не слушайте
То есть вы не проверили и советуете только основываясь на своё внутреннее ощущение, что за год в движке уж точно этот момент доработали?
Я вот в свою очередь думаю, что год назад как была эта информация актуальна, так и сейчас актуальна, потому что зачем допиливать оптимизацию устаревшнего arguments, раз уже активно внедряют es2015-es2016 и rest parameters
Попробуйте http://photoswipe.com/ (правда придется потратить время, чтобы прикрутить к ExtJS, но в целом ничего сложного)
Нет зависимостей, настраиваемый toolbar, любые кнопки, выпадающие меню, события, производительность (актуально для старых устройств), жесты, анимации приближения, swipe-to-close и т.д. Но для изображений требуется указывать width и height при инициализации, что может стать минусом
Тогда о чем и к чему речь, если я предлагаю вовсе отказаться от arguments и заменить его на Rest parameters + babel, чтобы утечек оптимизации не было? А вы предлагает вариант, где снова тянуть за собой arguments, да еще и как оператор spread. Es6 вообще подразумевает, что вы забудете как пишется arguments.
И кстати, Babel тут наоборот правильно всё делает, конструкция [...arguments] и до преобразования не «В исходном варианте утечки нет, после бабеля появилась», а наоборот, потому что это сложение с arguments, что приводит к деоптимизации. И как раз babel не вправе делать из версии с утечкой версию где нет утечки оптимизации (даже если умеет и знает что такая проблема есть), потому что в исходной версии она есть.
И если цель использовать arguments в качестве оператора spread
То в случае перехода на rest параметры:
function test(...args) {
var newArgs = [...args]
}
babel преобразует его правильным образом:
function test() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var newArgs = [].concat(args);
}
function bad2() {
return [].call.slice(arguments, 1);
}
Если же вы пытаетесь передать arguments в какую-нибудь другую функцию (например, делаете [].slice.call(arguments, 1)), то Crankshaft вообще откажется оптимизировать вашу функцию.
Например, функцию console.log() не получится сделать так, чтобы можно было обойтись без arguments, ну или max(21, 34, 54, 345, 1) какой-нибудь
Просто сейчас можно перейти на ...rest параметры, и очевиднее, и деоптимизаций не будет, так как Rest parameters создают обычный массив, хоть как его используй
При этом babel при преобразовании в es5 сам оптимизирует этот момент, чтобы деоптимизаций не было
Поэтому, кстати, в 2016 году куда полезнее учить связке es2015+babel, чем держать в голове все эти особенности с оптимизациями. По крайней мере на странных вещах, вроде arguments, попасться будет сложнее
Сначала найдёт все элементы, потом из них выберет те, которые внутри .box, потом от них возьмет :last-child
Как будет на самом деле — неизвестно, движок css современных браузеров загадка, до тех пор, пока кто нибудь не возьмется провести актуальное исследование
Одно ясно точно, если используется .box > *:last-child, и хочется привести к более БЭМ подходу, то есть несколько вариантов, например использование модификаторов:
Вот именно потому что вы не знаете как на самом деле и не знаете как будет завтра, хак с "* + X" использовать не стоит, и лучше опираться на стандарт, а не конкретную реализацию браузера
Ждал именно этого замечания. Да, сейчас браузер разбирает справа налево, но в случае с "* + X" нет гарантии, что браузер не преобразует этот селектор перед разбором в «X + *» для каких-то своих оптимизаций
Так же как нет гарантий, что следующее поколение движков не начнет разбирать селекторы слева направо
Тоесть использование "* + X" это хак, который может перестать работать, поэтому я и написал, что есть проблема в том числе и с оптимизированостью, потому что условно браузер должен просмотреть все элементы, но так как мы знаем, что браузер разбирает справо налево, то мы абузим «недокументированную» фичу, если продолжаем так делать
Может оно и короче и делает тоже самое, но имеет проблемы с методологией подхода (в рамках БЭМ, раз тут БЭМ), читаемостью и оптимизированностью (так как любое * заставит просмотреть все элементы), в то время как
.news__list-item:not(:first-child)
будет работать только с уже выбранным массивом .news__list-item
Да и визуально сразу понятно что речь о .news__list-item в рамках которого любой элемент кроме :first-child
Не нужна операция сложения, но нужно открывать и закрывать кавычки, поэтому это не сильно отличается от js варианта с +
В случае с `` как раз ни кавычки, ни сложение не требуется, тем и удобен
Например, для шаблонизатора где учитываются отступы для формирования dom, можно сделать так
var html = template.compile(`
extends layout
block main
include menu
ul.submenu
li.item home
li.item about
block footer
.end footer text
`);
Соответственно, даже вариант без сложения, с постоянной расстановкой кавычек был бы уже не удобен
Для теоретического async-await пока вариант явно отказаться либо от ловли ошибок, либо от оптимизаций (интересно как с этим дела в Edge). Может потому и не спешат внедрять
Кстати, в V8 уже оптимизировали некоторые моменты из числа убийц:
И вполне возможно скоро можно будет не так активно задумываться над убийцами оптимизаций
Добавление в любом месте try-catch (даже пустого) приводит к:
Вот еще до кучи вариант со стрелочными функциями (которые, как известно, дешевле и быстрее создаются и вызываются, и вовсе не имеют arguments):
Результат:
После работы бабеля получается тоже оптимизированная функция:
Проверил так же различные варианты стрелочных функций (в том числе и в прототипах), они всегда оптимизировались (по крайней мере не удалось найти вариант, чтобы оптимизации не было)
Ночные сборки 6.0.0 ноды: https://nodejs.org/download/nightly/
2. теперь и вы убедились, что ваш совет и вывод про статью были ошибочны
3-5. Невозможно просто заинлайнить, оптимизируется как и ожидалось
Итого. Используйте es6 + babel и никого не слушайте
Я вот в свою очередь думаю, что год назад как была эта информация актуальна, так и сейчас актуальна, потому что зачем допиливать оптимизацию устаревшнего arguments, раз уже активно внедряют es2015-es2016 и rest parameters
Не поможет
«Или даже ...args»
Поможет
«Да и вообще сейчас лучше вообще Array.from(arguments) использовать.»
Так делать не стоит
Нет зависимостей, настраиваемый toolbar, любые кнопки, выпадающие меню, события, производительность (актуально для старых устройств), жесты, анимации приближения, swipe-to-close и т.д. Но для изображений требуется указывать width и height при инициализации, что может стать минусом
И кстати, Babel тут наоборот правильно всё делает, конструкция [...arguments] и до преобразования не «В исходном варианте утечки нет, после бабеля появилась», а наоборот, потому что это сложение с arguments, что приводит к деоптимизации. И как раз babel не вправе делать из версии с утечкой версию где нет утечки оптимизации (даже если умеет и знает что такая проблема есть), потому что в исходной версии она есть.
babel преобразует его правильным образом:
На выходе получается правильная версия, без утечки:
Try it out выдает тот же результат
http://mrale.ph/blog/2015/04/12/jsunderhood.html
Просто сейчас можно перейти на ...rest параметры, и очевиднее, и деоптимизаций не будет, так как Rest parameters создают обычный массив, хоть как его используй
При этом babel при преобразовании в es5 сам оптимизирует этот момент, чтобы деоптимизаций не было
Станет:
Поэтому, кстати, в 2016 году куда полезнее учить связке es2015+babel, чем держать в голове все эти особенности с оптимизациями. По крайней мере на странных вещах, вроде arguments, попасться будет сложнее
Как будет на самом деле — неизвестно, движок css современных браузеров загадка, до тех пор, пока кто нибудь не возьмется провести актуальное исследование
Одно ясно точно, если используется .box > *:last-child, и хочется привести к более БЭМ подходу, то есть несколько вариантов, например использование модификаторов:
Так же как нет гарантий, что следующее поколение движков не начнет разбирать селекторы слева направо
Тоесть использование "* + X" это хак, который может перестать работать, поэтому я и написал, что есть проблема в том числе и с оптимизированостью, потому что условно браузер должен просмотреть все элементы, но так как мы знаем, что браузер разбирает справо налево, то мы абузим «недокументированную» фичу, если продолжаем так делать
будет работать только с уже выбранным массивом .news__list-item
Да и визуально сразу понятно что речь о .news__list-item в рамках которого любой элемент кроме :first-child
В случае с `` как раз ни кавычки, ни сложение не требуется, тем и удобен
Например, для шаблонизатора где учитываются отступы для формирования dom, можно сделать так
Соответственно, даже вариант без сложения, с постоянной расстановкой кавычек был бы уже не удобен
Или
Но тут, как минимум, не просто запись в несколько строк, а template literals