All streams
Search
Write a publication
Pull to refresh
161
1.4
Send message
Вполне может быть, в реализации промисов 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

И вполне возможно скоро можно будет не так активно задумываться над убийцами оптимизаций
Видимо нет, потому что в хроме:
function testFunction() {
    new Promise((r,j) => { throw 1; }).catch(err => console.log('error=', err))
}

Function is optimized

Добавление в любом месте try-catch (даже пустого) приводит к:
Function is not optimized
phpMyAdmin можно легко заменить на Adminer, он и mysql и postgresql поддерживает
Спасибо за инструкцию как запускать проверку в браузере

Вот еще до кучи вариант со стрелочными функциями (которые, как известно, дешевле и быстрее создаются и вызываются, и вовсе не имеют 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
«Если же вы пытаетесь передать arguments в какую-нибудь другую функцию, то Crankshaft вообще откажется оптимизировать вашу функцию.»
«это не так со включенным флагом 'use strict';»
Не поможет

«Или даже ...args»
Поможет

«Да и вообще сейчас лучше вообще Array.from(arguments) использовать.»
Так делать не стоит
Попробуйте 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);
}

Проверил на последней версии (или что-то тут не так?):
$ ./node_modules/.bin/babel -V
6.6.5 (babel-core 6.7.4)

На выходе получается правильная версия, без утечки:
$ cat ./src/index.js 
function test(...rest) {
  [].slice.call(rest)
}

$ cat ./lib/index.js 
"use strict";

function test() {
  for (var _len = arguments.length, rest = Array(_len), _key = 0; _key < _len; _key++) {
    rest[_key] = arguments[_key];
  }

  [].slice.call(rest);
}

Try it out выдает тот же результат
function bad2() {
  return [].call.slice(arguments, 1);
}

Если же вы пытаетесь передать arguments в какую-нибудь другую функцию (например, делаете [].slice.call(arguments, 1)), то Crankshaft вообще откажется оптимизировать вашу функцию.

http://mrale.ph/blog/2015/04/12/jsunderhood.html
Например, функцию console.log() не получится сделать так, чтобы можно было обойтись без arguments, ну или max(21, 34, 54, 345, 1) какой-нибудь

Просто сейчас можно перейти на ...rest параметры, и очевиднее, и деоптимизаций не будет, так как Rest parameters создают обычный массив, хоть как его используй

При этом babel при преобразовании в es5 сам оптимизирует этот момент, чтобы деоптимизаций не было
function test(...rest) {
  [].slice.call(rest)
}

Станет:
function test() {
  for (var _len = arguments.length, rest = Array(_len), _key = 0; _key < _len; _key++) {
    rest[_key] = arguments[_key];
  }

  [].slice.call(rest);
}

Поэтому, кстати, в 2016 году куда полезнее учить связке es2015+babel, чем держать в голове все эти особенности с оптимизациями. По крайней мере на странных вещах, вроде arguments, попасться будет сложнее
Сначала найдёт все элементы, потом из них выберет те, которые внутри .box, потом от них возьмет :last-child
Как будет на самом деле — неизвестно, движок css современных браузеров загадка, до тех пор, пока кто нибудь не возьмется провести актуальное исследование

Одно ясно точно, если используется .box > *:last-child, и хочется привести к более БЭМ подходу, то есть несколько вариантов, например использование модификаторов:
<div class="box">
  <div class="box__item box__item_1">item1</div>
  <div class="box__item box__item_2">item2</div>
  <div class="box__item box__item_3">item3</div>
  <div class="box__item box__item_1">item4</div>
</div>


.box {
&__item_1 { margin-bottom: 30px }
&__item_2 { margin-bottom: 40px }
&__item_3 { margin-bottom: 25px }
&__item:last-child { margin-bottom: 0; }
}
Вот именно потому что вы не знаете как на самом деле и не знаете как будет завтра, хак с "* + 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
`);

Соответственно, даже вариант без сложения, с постоянной расстановкой кавычек был бы уже не удобен
В C есть 2 способа писать строки в несколько строк, но они ничем особо не отличаются от вариантов в js:
var jsstr =
    "test" +
    "middle" +
    "end";

Или
var jsstr = "\
test\
middle\
end";

Но тут, как минимум, не просто запись в несколько строк, а template literals

Information

Rating
1,448-th
Registered
Activity