Idąc za pytaniem Extending String.prototype performance jestem naprawdę zaintrygowany, bo samo dodanie "use strict"
do String.prototype
metody poprawiło wydajność 10 razy. Wyjaśnienie przez Bergi jest krótki i nie mi to wyjaśnić. Dlaczego jest tak dramatyczna różnica między dwoma prawie identycznymi metodami, które różnią się tylko "use strict"
u góry? Czy możesz wyjaśnić bardziej szczegółowo i za pomocą teorii stojącej za tym?
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');
Wynik:
proto: 101 ms
proto-strict: 7.5 ms
javascript
performance
exebook
źródło
źródło
this[i] === char
i sprawdzić, czy zauważysz tę samą różnicę?this[i] === char
w środowisku DOM i wynik jest taki samcount
funkcję,this
parametr musi być rzutowany na obiekt typu string zamiast na literał łańcuchowy, podczas gdy w trybie ścisłym nie musi to działać, aby działać poprawnie. Dlaczego tak się dzieje, jest poza mną, jestem bardzo zainteresowany odpowiedzią.this
, ale w trybie ścisłym pomija ten krok, więc otrzymujesz prymitywny ciąg lub cokolwiek innego, co zostało przewidzianethis
."use strict";
wszędzie chłopców! GooooldOdpowiedzi:
W trybie ścisłym
this
kontekst nie musi być obiektem. Jeśli wywołasz funkcję na obiekcie niebędącym obiektem,this
będzie to tylko ten obiekt niebędący obiektem.W przeciwieństwie do tego, w trybie nieścisłości,
this
kontekst jest zawsze najpierw zawijany w obiekt, jeśli nie jest jeszcze obiektem. Na przykład,(42).toString()
pierwsze okłady42
wNumber
obiekt, a następnie zwracaNumber.prototype.toString
się doNumber
obiektu jakothis
kontekst. W trybie ścisłym Thethis
kontekst pozostało nietknięte i tylko rozmowyNumber.prototype.toString
z42
jakthis
kontekst.(function() { console.log(typeof this); }).call(42); // 'object' (function() { 'use strict'; console.log(typeof this); }).call(42); // 'number'
W twoim przypadku wersja w trybie nieostrym spędza dużo czasu na zawijaniu i rozpakowywaniu prymitywów
string
s doString
opakowań obiektów iz powrotem. Z drugiej strony wersja trybu ścisłego działa bezpośrednio na prymitywachstring
, co poprawia wydajność.źródło
with
również trochę pomaga przy każdym wyszukiwaniu zmiennych iirc.with
pomaga niezmiernie, ponieważ pozwala przeglądarce określić, które wyrażenie zmiennej odnosi się do której zmiennej.this
jest „bardziej rygorystyczny” niż zawsze-przedmiotthis
.this
jestnull
lubundefined
, który byłby globalnym obiektem w trybie niechlujstwa.this
” kontra „opakowującythis
”, jeśli chcesz. Opakowania obiektów to kludge, które nigdy nie powinny istnieć, więc sensowne jest, aby tryb ścisły unikał ich bardziej, gdy to możliwe.