После вопроса « Расширение производительности String.prototype» я был очень заинтригован, потому что простое добавление "use strict"
к String.prototype
методу улучшило производительность в 10 раз. Объяснение по Бергам коротко и не объясняет мне. Почему существует такая резкая разница между двумя почти идентичными методами, которые отличаются только "use strict"
вверху? Можете ли вы объяснить более подробно и с теорией, стоящей за этим?
String.prototype.count = function(char) {
var n = 0;
for (var i = 0; i < this.length; i++)
if (this[i] == char) n++;
return n;
};
String.prototype.count_strict = function(char) {
"use strict";
var n = 0;
for (var i = 0; i < this.length; i++)
if (this[i] == char) n++;
return n;
};
// Here is how I measued speed, using Node.js 6.1.0
var STR = '0110101110010110100111010011101010101111110001010110010101011101101010101010111111000';
var REP = 1e4;
console.time('proto');
for (var i = 0; i < REP; i++) STR.count('1');
console.timeEnd('proto');
console.time('proto-strict');
for (var i = 0; i < REP; i++) STR.count_strict('1');
console.timeEnd('proto-strict');
Результат:
proto: 101 ms
proto-strict: 7.5 ms
javascript
performance
exebook
источник
источник
this[i] === char
и увидеть, получите ли вы такую же разницу?this[i] === char
в среде DOM, и результат тот жеcount
функцию,this
параметр должен быть приведен к строковому объекту, а не к строковому литералу, тогда как в строгом режиме это не обязательно для правильной работы. Почему это так, мне непонятно, мне очень интересен ответ.this
, но в строгом режиме он пропускает этот шаг, поэтому вы получаете примитивную строку или все, что было предусмотреноthis
."use strict";
везде мальчиков! GooooldОтветы:
В строгом режиме
this
контекст не обязательно должен быть объектом. Если вы вызываете функцию для не-объекта, этоthis
будет просто не-объект.Напротив, в нестрогом режиме
this
контекст всегда сначала оборачивается в объект, если это еще не объект. Например,(42).toString()
первые обертывании42
вNumber
объекте , а затем вызываютNumber.prototype.toString
сNumber
объектом в качествеthis
контекста. В строгом режимеthis
контекст остается нетронутым и просто вызываетсяNumber.prototype.toString
с контекстом42
asthis
.В вашем случае версия нестрогого режима тратит много времени на перенос и развертывание примитивов
string
вString
обертки объектов и обратно. С другой стороны, версия в строгом режиме напрямую работает с примитивомstring
, что улучшает производительность.источник
with
также немного помогает при поиске каждой переменной iirc.with
помогает, поскольку позволяет браузеру понять, какое выражение переменной относится к какой переменной.this
«строже», чем всегда-объектthis
.this
isnull
илиundefined
, который будет глобальным объектом в небрежном режиме.this
» против «оберткиthis
», если хотите. Обертки объектов - это кладж, которого никогда не должно было существовать, поэтому имеет смысл, чтобы строгий режим избегал их больше, когда это возможно.