2015-08-24 52 views
5
var example = function() { 
    console.log(typeof this); 
    return this; 
}; 

W trybie ścisłym: example.call('test') # prints 'string'Funkcja.prototype.call zmienia ten typ, poza trybem ścisłym; czemu?

Inaczej example.call('test') # prints 'object'

Jednak console.log(example.call('test')) drukuje test (jak można się spodziewać)

Dlaczego Function.call zmiana typeof 'test' === 'string' związany this wewnątrz example?

+2

To nie 'call' który zmienia wszystko. Jest to niedbały tryb, który wymusza wartość 'this' na obiekcie (tutaj, obiekcie' String'). – Bergi

Odpowiedz

5

Podczas korzystania call() i ustawienie this argument do prymitywnego wartości, że wartość prymitywny zawsze konwertowane do obiektu, więc masz obiektu String zamiast prymitywnego ciąg

String {0: "t", 1: "e", 2: "s", 3: "t", length: 4, ... 

Dokumentacja call() na MDN stwierdza, że ​​

thisArg
Wartość this przewidywała wywołanie funkcji.
Należy zauważyć, że może to nie być rzeczywista wartość widoczna dla metody: jeśli metoda jest funkcją w trybie nie ścisłym, null i undefined zostaną zastąpione obiektem globalnym, , a wartości pierwotne zostaną przekonwertowane na obiekty.

Więc w trybie non-ścisłe pierwotna wartość ciąg jest konwertowany na obiekt, jest również określona w ECMA standard, Annex C

ścisłego ograniczenia trybu i wyjątki
Jeśli this jest oceniana w ramach kodu trybu ścisłego, a następnie wartość this nie jest przymuszana do obiektu.
Ta wartość null lub undefined nie jest konwertowana na obiekt globalny, a wartości pierwotne nie są konwertowane na obiekty opakowania.
Wartość this przekazywane poprzez wywołanie funkcji (w tym połączeń wykonanych przy użyciu Function.prototype.apply i Function.prototype.call) nie zniewalać przekazywana wartość this do obiektu

+0

Nie krytykę swojego postu, ale "zapakowane"? Dlaczego ludzie niepotrzebnie wprowadzają bezsensowny żargon, gdy specyfikacja mówi o wiele bardziej spójnym "przymuszonym do obiektu"? – RobG

+0

@RobG - Kto wie, to kopiowanie/wklejanie prosto z MDN, który używa "boxed", więc kontynuowałem używanie tego terminu. – adeneo

+1

Nie mówi już "zapakowane". ;-) – RobG