2011-01-28 12 views
8

Jaki jest najlepszy sposób, aby dowiedzieć się, czy zmienna jest ciągiem czy nie (i, podobnie, liczba, wartość logiczna, itd.)?Sprawdzanie typu zmiennej

Zazwyczaj znajdziesz:

function isString(value) { 
    return typeof value === 'string'; 
} 

Ale ludzie zapominają, że można także utworzyć ciąg obiektów bezpośrednio za pomocą var foo = new String("bar"); - czy to jest dobry pomysł, czy nie jest to zupełnie inna sprawa.

Więc co jest do zrobienia tutaj? Mogę myśleć - i widziałem - różne podejścia (nieco uproszczone):

// option 1 
function isString(value) { 
    return (typeof value === 'string') || 
      /^function String\(\)/.test(value.constructor + ''); 
} 

lub

// option 2 
function isString(value) { 
    return (typeof value === 'string') || 
      (value.constructor === String); 
} 

lub

// option 3 
function isString(value) { 
    return (typeof value === 'string') || 
      value instanceof String; 
} 

tam jest "najlepszy" sposób, aby przejść na ten temat ? A może wszystkie są równoważne?

Odpowiedz

5

Spośród trzech istniejących opcji, pierwszy czuje się dość hacky do mnie, ponieważ używa wyrażenia regularnego, aby przetestować ciąg znaków reprezentujący value.constructor. Działa, ale nadal czuje się hacky (może to tylko ja).

Druga opcja będzie działać tylko dla napisowych, ciągów utworzonych z łączenie istniejących obiektów i przedmiotów wykonanych z konstruktora new String(), natomiast trzecia opcja powinna działać z przedmiotów wykonanych z konstruktora new String() lub innego obiektu, który dziedziczy z String()(Nie jestem pewien co do dziedziczenia JavaScript, czy ktoś może to potwierdzić?).

Właściwość constructor istnieje również dla prymitywów/literałów, a nie tylko obiektów otoki utworzonych za pomocą new. To sprawia, że ​​czek typeof W drugim wariancie zupełnie zbędny:

function isString(value) { 
    return value.constructor === String; 
} 

alert(isString("test1"));    // true 
alert(isString(new String("test2"))); // true 

Jednak w przeciwieństwie do trzeciej opcji nie może pracować z obiektami z konstruktorów innych niż String() które dziedziczą z String().

Moja odpowiedź używa strun jako przykład, aby odzwierciedlić pytanie, ale sam pomysł dotyczy Number, Boolean, Function, Object, Array i innych typów.

+0

Neat, nie wiedziałem, że (przynajmniej ja nigdy nie myślał o tym;) Czy naprawdę nie odpowiedzieć na pytanie, choć. – n3rd

+0

@ n3rd: Jak nie jest to odpowiedź na pytanie inne niż to, że nie jest jedną z trzech istniejących opcji? – BoltClock

+0

+1. Właśnie miał to opublikować. Czy jednak te podklasy chwytające (wstrzymujące) Stringa? – Skurmedel