Sprawdzanie typów obiektów w JS odbywa się za pomocą instanceof, np
obj instanceof Array
To nie zadziała, jeśli obiekt zostanie przekazany poza granice klatki, ponieważ każda klatka ma swój własny Arrayobiekt. Możesz obejść ten problem, sprawdzając wewnętrzną właściwość [[Class]] obiektu. Aby go zdobyć, użyj Object.prototype.toString()(to gwarantuje działanie ECMA-262):
Object.prototype.toString.call(obj) === '[object Array]'
Obie metody będą działać tylko dla rzeczywistych tablic, a nie obiektów przypominających tablice, takich jak listy argumentsobiektów lub węzłów. Ponieważ wszystkie obiekty podobne do tablic muszą mieć lengthwłaściwość numeryczną , sprawdziłbym to następująco:
typeof obj !== 'undefined' && obj !== null && typeof obj.length === 'number'
Należy pamiętać, że ciągi przejdą tę kontrolę, co może prowadzić do problemów, ponieważ IE nie zezwala na dostęp do znaków ciągu według indeksu. Dlatego możesz chcieć zmienić typeof obj !== 'undefined'na, typeof obj === 'object'aby wykluczyć prymitywy i obiekty hosta z typami różniącymi się od wszystkich 'object'. To nadal będzie przepuszczać obiekty tekstowe, które musiałyby zostać wykluczone ręcznie.
W większości przypadków tak naprawdę chcesz wiedzieć, czy możesz iterować po obiekcie za pomocą indeksów liczbowych. Dlatego dobrym pomysłem może być sprawdzenie, czy obiekt ma 0zamiast tego nazwaną właściwość , co można zrobić za pomocą jednego z poniższych sprawdzeń:
typeof obj[0] !== 'undefined' // false negative for `obj[0] = undefined`
obj.hasOwnProperty('0') // exclude array-likes with inherited entries
'0' in Object(obj) // include array-likes with inherited entries
Rzutowanie na obiekt jest niezbędne do poprawnego działania dla prymitywów przypominających tablice (tj. Łańcuchów).
Oto kod do niezawodnych kontroli tablic JS:
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
i iterowalne (tj. niepuste) obiekty przypominające tablice:
function isNonEmptyArrayLike(obj) {
try { // don't bother with `typeof` - just access `length` and `catch`
return obj.length > 0 && '0' in Object(obj);
}
catch(e) {
return false;
}
}