На основании http://jsperf.com/bind-vs-emulate/6,, который добавляет для сравнения версию es5-shim, похоже, что виновником является дополнительная ветвь, а instanceof
, что связанная версия должна выполнить, чтобы проверить, вызывается ли она как конструктор .
Каждый раз, когда запускается связанная версия, исполняемый код по существу:
if (this instanceof bound) {
// Never reached, but the `instanceof` check and branch presumably has a cost
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
// args is [] in your case.
// So the cost is:
// * Converting (empty) Arguments object to (empty) array.
// * Concating two empty arrays.
}
В исходном коде V8 эта проверка отображается (внутри boundFunction
) как
if (%_IsConstructCall()) {
return %NewObjectFromBound(boundFunction);
}
( Открытая текстовая ссылка на v8natives.js , когда умирает Поиск кода Google.)
Немного удивительно, что, по крайней мере, для Chrome 16 версия es5-shim все еще быстрее, чем нативная версия. И что другие браузеры имеют довольно разные результаты для es5-shim против native. Предположение: возможно, %_IsConstructCall()
даже медленнее, чем this instanceof bound
, возможно, из-за пересечения границ собственного кода / кода JS. И, возможно, другие браузеры имеют гораздо более быстрый способ проверки вызова [[Construct]]
.