Odpowiedzi:
Możesz użyć typeof
operatora:
var booleanValue = true;
var numericalValue = 354;
var stringValue = "This is a String";
var stringObject = new String( "This is a String Object" );
alert(typeof booleanValue) // displays "boolean"
alert(typeof numericalValue) // displays "number"
alert(typeof stringValue) // displays "string"
alert(typeof stringObject) // displays "object"
Przykład z tej strony . (Przykład został jednak nieco zmodyfikowany).
Nie będzie to działało zgodnie z oczekiwaniami w przypadku ciągów utworzonych za pomocą new String()
, ale jest to rzadko używane i zalecane przeciwko [1] [2] . Zobacz inne odpowiedzi, jak sobie z nimi poradzić, jeśli chcesz.
new String('foo')
, ale to nie ma znaczenia, ponieważ łańcuchy obiektowe są bezwartościową funkcją, której nie powinieneś używać. Przewodnik po stylu Google zabrania ich , Douglas Crockford chce, aby były przestarzałe i żadne biblioteki ich nie używają. Udawaj, że nie istnieją i używaj ich typeof
bez strachu.
Oto, co działa dla mnie:
if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
instanceof
sprawdzanie tutaj jest bezcelowe, chyba że podążasz za jakimś bardzo niezwykłym praktyk kodowania, a ta odpowiedź nic nie wyjaśnia, co robi i dlaczego możesz go użyć. Jedynym powodem, dla którego będziesz go kiedykolwiek potrzebować, jest użycie ciągów zawijanych w obiektach, ale ciągi zawijane w obiekty są bezwartościową funkcją, której nikt nie używa, a Google i Crockford potępiają jako złą praktykę ( google-styleguide.googlecode.com/svn/ trunk /… , crockford.com/javascript/recommend.html ).
typeof
i instanceof
wydaje się dobrą radą, jeśli Twój kod może zostać wywołany przez inne osoby. @ MarkAmery'spostmessage
krawędzi znaczenie, jeśli pytasz „co ja właśnie postmessage
d?”. - ale można oczekiwać, że zostanie to obsłużone w interfejsie i nie będzie mogło się rozprzestrzeniać. Gdzie indziej, wydaje się poprawne posługiwanie się nieaktualnymi metodami kodowania, nawet jeśli niektóre estetyki JS ich nie pochwalają. NIGDY nie komentuj swojego kodu jako akceptującego String, chyba że tak naprawdę!
Ponieważ ponad 580 osób głosowało na niepoprawną odpowiedź, a ponad 800 głosowało na działającą, ale podobną do strzelby odpowiedź, pomyślałem, że warto powtórzyć moją odpowiedź w prostszej formie, którą każdy może zrozumieć.
function isString(x) {
return Object.prototype.toString.call(x) === "[object String]"
}
Lub inline (mam do tego konfigurację UltiSnip):
Object.prototype.toString.call(myVar) === "[object String]"
Do Twojej wiadomości, odpowiedź Pablo Santa Cruz jest zła, ponieważ typeof new String("string")
jestobject
Odpowiedź DRAX-a jest dokładna i funkcjonalna i powinna być poprawną odpowiedzią (ponieważ Pablo Santa Cruz jest zdecydowanie niepoprawna i nie będę się kłócił przeciwko głosowaniu powszechnemu).
Jednak ta odpowiedź jest również zdecydowanie poprawna i faktycznie najlepsza odpowiedź (z wyjątkiem być może sugestii użycia lodash / podkreślenia ). zrzeczenie się odpowiedzialności: Przyczyniałem się do bazy kodu lodash 4.
Moja pierwotna odpowiedź (która oczywiście przeleciała nad wieloma głowami) brzmi:
Przekodowałem to z underscore.js:
['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'].forEach(
function(name) {
window['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
};
});
To zdefiniuje isString, isNumber itp.
W Node.js można to zaimplementować jako moduł:
module.exports = [
'Arguments',
'Function',
'String',
'Number',
'Date',
'RegExp'
].reduce( (obj, name) => {
obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
return obj;
}, {});
[edytuj]: Object.prototype.toString.call(x)
działa również w celu rozdzielenia funkcji i funkcji asynchronicznych:
const fn1 = () => new Promise((resolve, reject) => setTimeout(() => resolve({}), 1000))
const fn2 = async () => ({})
console.log('fn1', Object.prototype.toString.call(fn1))
console.log('fn2', Object.prototype.toString.call(fn2))
global || window
zamiast window
jednak, że byłoby to złe podejście do rozwiązania problemu nie powinien mieć w pierwszej kolejności).
myObject+"" === myObject
czy obiekt jest ciągiem (a nawet lepiej, nie pisałbym sprawdzania w systemie typu opartym na zachowaniu).
toString
w Object.prototype
. Twierdzę więc, że poleganie na toString
sprawdzaniu typu obiektu jest w najlepszym razie złą praktyką.
Polecam korzystanie z wbudowanych funkcji jQuery lub lodash / Underscore . Są prostsze w użyciu i łatwiejsze do odczytania.
Każda funkcja obsłuży wspomniany przypadek DRAX ... to znaczy oba sprawdzają, czy (A) zmienna jest literałem ciągu lub (B) jest instancją obiektu String. W obu przypadkach funkcje te poprawnie identyfikują wartość jako ciąg.
lodash / Underscore.js
if(_.isString(myVar))
//it's a string
else
//it's something else
jQuery
if($.type(myVar) === "string")
//it's a string
else
//it's something else
Zobacz dokumentację lodash dla _.isString (), aby uzyskać więcej informacji.
Zobacz dokumentację jQuery dla $ .type () po więcej szczegółów.
_.every()
jest trochę mylące w użyciu i coś tak prostego, jak _.isBoolean()
mylące devy w moim towarzystwie. Deweloper błędnie pomyślał, że byłoby fałszem, gdyby wartość była wartością logiczną i była fałszywa. Angielski jest dla mnie łatwiejszy do odczytania niż niemiecki, ponieważ nie znam niemieckiego. Naucz się JavaScript, a wszystko to będzie miało sens.
function isString (obj) {
return (Object.prototype.toString.call(obj) === '[object String]');
}
Widziałem to tutaj:
http://perfectionkills.com/instanceof-consanted-harmful-or-how-to-write-a-robust-isarray/
Object.prototype.toString.call(obj) === '[object String]'
?
(x === y)
lepszą czytelność niż x === y
?
Najlepszym sposobem:
var s = 'String';
var a = [1,2,3];
var o = {key: 'val'};
(s.constructor === String) && console.log('its a string');
(a.constructor === Array) && console.log('its an array');
(o.constructor === Object) && console.log('its an object');
(o.constructor === Number || s.constructor === Boolean) && console.log('this won\'t run');
Każdy z nich został skonstruowany za pomocą odpowiedniej funkcji klasy, takiej jak „new Object ()” itp.
Ponadto, pisanie kaczką: „Jeśli wygląda jak kaczka, chodzi jak kaczka i pachnie jak kaczka - to musi być szyk”. Oznacza to, sprawdź jej właściwości.
Mam nadzieję że to pomoże.
Pamiętaj, że zawsze możesz używać kombinacji podejść. Oto przykład użycia wbudowanej mapy działań z typof :
var type = { 'number': Math.sqrt.bind(Math), ... }[ typeof datum ];
Oto bardziej „rzeczywisty” przykład użycia map wbudowanych:
function is(datum) {
var isnt = !{ null: true, undefined: true, '': true, false: false, 0: false }[ datum ];
return !isnt;
}
console.log( is(0), is(false), is(undefined), ... ); // >> true true false
Ta funkcja użyłaby [niestandardowego] „rzutowania typu” - raczej „mapowania typu - / - wartości” - aby dowiedzieć się, czy zmienna rzeczywiście „istnieje”. Teraz możesz rozdzielić te paskudne włosy pomiędzy null
i 0
!
Wiele razy nawet nie dbasz o jego typ . Innym sposobem na uniknięcie pisania jest łączenie zestawów typu kaczka:
this.id = "998"; // use a number or a string-equivalent
function get(id) {
if (!id || !id.toString) return;
if (id.toString() === this.id.toString()) http( id || +this.id );
// if (+id === +this.id) ...;
}
Oba Number.prototype
i String.prototype
mają .toString() method
. Właśnie upewniłeś się, że ekwiwalent ciągu liczby był taki sam, a następnie upewniłeś się, że przekazałeś go do http
funkcji jako Number
. Innymi słowy, nie obchodziło nas nawet, jaki był tego typu.
Mam nadzieję, że dajesz więcej do pracy :)
(o.constructor === Number || s.constructor === Boolean)
). Anegdotycznie parseInt
i NaN
są delikatnymi, ale potężnymi narzędziami. Pamiętaj tylko, że NIE-Liczba nie jest NIE-Liczba i można zdefiniować niezdefiniowany.
if(thing.call) { 'its a function'; }
lub if(thing.defineProperties) { 'its an object'; }
. Dzięki za wkład, axkibe!
Nie rozumiem szczerze, dlaczego typeof
w takim przypadku nie można po prostu użyć :
if (typeof str === 'string') {
return 42;
}
Tak, nie powiedzie się w przypadku łańcuchów opakowanych w obiekty (np. new String('foo')
), Ale są one powszechnie uważane za złą praktykę i większość współczesnych narzędzi programistycznych może zniechęcać do ich używania. (Jeśli widzisz, po prostu to napraw!)
Object.prototype.toString
Sztuką jest coś, co wszyscy deweloperzy front-end został uznany za winnego robi jeden dzień w ich karierze, ale nie pozwól, by oszukać jego polerowania mądry: pęknie jak tylko coś małpy plastra prototyp obiektu:
const isString = thing => Object.prototype.toString.call(thing) === '[object String]';
console.log(isString('foo'));
Object.prototype.toString = () => 42;
console.log(isString('foo'));
Lubię używać tego prostego rozwiązania:
var myString = "test";
if(myString.constructor === String)
{
//It's a string
}
undefined
i null
, i wciąż uzyskania właściwej odpowiedzi dla pustych ciągów (zarówno ''
i new String('')
).
(mystring || false) && mystring.constructor === String
. Użyłem wartości false, jeśli jest używana w funkcji, która musi zwrócić wartość logiczną.
To świetny przykład tego, dlaczego wydajność ma znaczenie:
Wykonanie czegoś tak prostego jak testowanie łańcucha może być kosztowne, jeśli nie zostanie wykonane poprawnie.
Na przykład, jeśli chciałbym napisać funkcję sprawdzającą, czy coś jest ciągiem, mógłbym to zrobić na dwa sposoby:
1) const isString = str => (Object.prototype.toString.call(str) === '[object String]');
2) const isString = str => ((typeof str === 'string') || (str instanceof String));
Oba są dość proste, więc co może wpłynąć na wydajność? Mówiąc ogólnie, wywołania funkcji mogą być kosztowne, szczególnie jeśli nie wiesz, co dzieje się w środku. W pierwszym przykładzie istnieje wywołanie funkcji do metody toString obiektu. W drugim przykładzie nie ma wywołań funkcji, ponieważ typeof i instanceof są operatorami. Operatory są znacznie szybsze niż wywołania funkcji.
Podczas testowania wydajności przykład 1 jest o 79% wolniejszy niż przykład 2!
Zobacz testy: https://jsperf.com/isstringtype
typeof str === 'string' || str instanceof String
(może upuścić nawias, który wolę w if (..)
przypadkach); niezależnie od tego, sprawdzanie zarówno typów pierwotnych, jak i typów obiektów w # 2 jest jasne i wystarczające. Te kontrole i tak powinny być „rzadkie”.
if (s && typeof s.valueOf() === "string") {
// s is a string
}
Działa zarówno z literałami łańcuchowymi, jak let s = 'blah'
i obiektowymilet s = new String('blah')
Pobrane z lodash:
function isString(val) {
return typeof val === 'string' || ((!!val && typeof val === 'object') && Object.prototype.toString.call(val) === '[object String]');
}
console.log(isString('hello world!')); // true
console.log(isString(new String('hello world'))); // true
Myślę, że rozwiązanie @customcommander powinno wystarczyć w 90% twoich przypadków:
typeof str === 'string'
Powinien ci dobrze służyć (po prostu dlatego, że zwykle nie ma powodu, aby to mieć) new String('something')
w kodzie).
Jeśli jesteś zainteresowany obsługą String
obiektu (na przykład oczekujesz, że różni się od firmy trzeciej), to użycie lodash jako sugerowanej @ ClearCloud8 wydaje się jasnym, prostym i eleganckim rozwiązaniem.
Sugerowałbym jednak ostrożność w stosunku do bibliotek takich jak lodash ze względu na ich wielkość. Zamiast robić
import _ from 'lodash'
...
_.isString(myVar)
Co przynosi cały ogromny obiekt lodash, sugerowałbym coś takiego:
import { isString as _isString } from 'lodash'
...
_isString(myVar)
Z prostym pakietowaniem powinieneś być w porządku (odnoszę się tutaj do kodu klienta).
Jeśli pracujesz w środowisku node.js, możesz po prostu użyć wbudowanej funkcji isString w utils.
const util = require('util');
if (util.isString(myVar)) {}
Edycja: jak wspomniano @Jehy, jest to przestarzałe od wersji 4.
typeof value === 'string'
zamiast”.
x = new String('x'); x.isString(x);
zwraca false . Istnieje util.types.isStringObject()
jednak wartość false dla x = 'x'
ciągu typu. Dwie funkcje narzędziowe, które absolutnie nie zapewniają żadnej użyteczności ...
Poniższa metoda sprawdzi, czy jakakolwiek zmienna jest ciągiem (w tym zmienne, które nie istnieją ).
const is_string = value => {
try {
return typeof value() === 'string';
} catch (error) {
return false;
}
};
let example = 'Hello, world!';
console.log(is_string(() => example)); // true
console.log(is_string(() => variable_doesnt_exist)); // false
Odkryłem również, że to też działa dobrze i jest znacznie krótsze niż w innych przykładach.
if (myVar === myVar + '') {
//its string
} else {
//its something else
}
Łącząc puste cudzysłowy, zamienia wartość w ciąg znaków. Jeśli myVar
jest już ciągiem, to instrukcja if się powiodła.
typeof
.
typeof
ale wciąż nieco szybszy niż toString
. Tak czy inaczej, chyba podoba mi się składnia wymuszania.
var s = new String('abc'); > s === s + '' > false
new String
cus, który tworzy rodzaj object
. w3schools.com/js/tryit.asp?filename=tryjs_string_object2
var a = new String('')
var b = ''
var c = []
function isString(x) {
return x !== null && x !== undefined && x.constructor === String
}
console.log(isString(a))
console.log(isString(b))
console.log(isString(c))
false
.
Uważam, że ta prosta technika jest przydatna do sprawdzania typu dla String -
String(x) === x // true, if x is a string
// false in every other case
const test = x =>
console.assert
( String(x) === x
, `not a string: ${x}`
)
test("some string")
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/) // assertion failed
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
Ta sama technika działa również dla Number -
Number(x) === x // true, if x is a number
// false in every other case
const test = x =>
console.assert
( Number(x) === x
, `not a number: ${x}`
)
test("some string") // assertion failed
test(123)
test(0)
test(/some regex/) // assertion failed
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
A dla RegExp -
RegExp(x) === x // true, if x is a regexp
// false in every other case
const test = x =>
console.assert
( RegExp(x) === x
, `not a regexp: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/)
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
To samo dla obiektu -
Object(x) === x // true, if x is an object
// false in every other case
NB, wyrażenia regularne, tablice i funkcje są również uważane za obiekty.
const test = x =>
console.assert
( Object(x) === x
, `not an object: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/)
test([ 5, 6 ])
test({ a: 1 })
test(x => x + 1)
Ale sprawdzanie tablicy jest nieco inne -
Array.isArray(x) === x // true, if x is an array
// false in every other case
const test = x =>
console.assert
( Array.isArray(x)
, `not an array: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/) // assertion failed
test([ 5, 6 ])
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
Ta technika nie działa jednak w przypadku funkcji -
Function(x) === x // always false
var x = new String(x); String(x)===x
zwraca false jednak ({}).toString.call(x).search(/String/)>0
zawsze wraca po sznurki
function isClass(x,re){return ({}).toString.call(x).search(re)>0;};
isClass("hello",/String/)
lub isClass(3,/Number/)
lubisClass(null,/Null/)
Prostym rozwiązaniem byłoby:
var x = "hello"
if(x === x.toString()){
// it's a string
}else{
// it isn't
}
toString()
funkcję
.toString
żadnych wartości; spróbuj, jeśli x, który ma być sprawdzony, ma wartość NULL lub jest niezdefiniowany, wyjątek
toString()
metoda może zostać przesłonięta i może zgłosić wyjątek (z powodu określonej implementacji), a sprawdzenie na pewno nie zadziała. Główną ideą jest to, że nie powinieneś wywoływać metod niezwiązanych z tym, co chcesz uzyskać. Nie mówię nawet o niepotrzebnych kosztach związanych z tą toString
metodą. Downvoting.
Pomocnik Typechecker:
function isFromType(variable, type){
if (typeof type == 'string') res = (typeof variable == type.toLowerCase())
else res = (variable.constructor == type)
return res
}
stosowanie:
isFromType('cs', 'string') //true
isFromType('cs', String) //true
isFromType(['cs'], Array) //true
isFromType(['cs'], 'object') //false
Również jeśli chcesz, aby był rekurencyjny (jak tablica, która jest obiektem), możesz użyć instanceof
.
( ['cs'] instanceof Object //true
)
Idę inną drogą do pozostałych tutaj, które próbują stwierdzić, czy zmienna jest konkretnym typem, czy też członkiem określonego zestawu.
JS opiera się na kaczce; jeśli coś trzeszczy jak struna, możemy i powinniśmy użyć tego jak struny.
Jest 7
ciąg? Dlaczego więc /\d/.test(7)
działa?
Jest {toString:()=>('hello there')}
ciąg? Dlaczego więc ({toString:()=>('hello there')}) + '\ngeneral kenobi!'
działa?
To nie są pytania, które powinny powyższe prace, chodzi o to robią.
Więc stworzyłem duckyString()
funkcję
Poniżej testuję wiele przypadków, które nie są pokrywane przez inne odpowiedzi. Dla każdego kodu:
duckyString()
normalizację danych wejściowych dla kodu, który oczekuje rzeczywistych ciągówtext = 'hello there';
out(text.replace(/e/g, 'E') + ' ' + 'hello there'.replace(/e/g, 'E'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = new String('oh my');
out(text.toUpperCase() + ' ' + 'oh my'.toUpperCase());
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = 368;
out((text + ' is a big number') + ' ' + ('368' + ' is a big number'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = ['\uD83D', '\uDE07'];
out(text[1].charCodeAt(0) + ' ' + '😇'[1].charCodeAt(0));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
function Text() { this.math = 7; }; Text.prototype = {toString:function() { return this.math + 3 + ''; }}
text = new Text();
out(String.prototype.match.call(text, '0') + ' ' + text.toString().match('0'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
Jest to w tym samym stylu, co !!x
w przeciwieństwie do x===true
testowania, czy coś jest podobne do tablicy, zamiast konieczności rzeczywistej tablicy.
obiekty jQuery; czy są tablice? Nie. Czy są wystarczająco dobre? Tak, możesz je dobrze uruchomić przez Array.prototype
funkcje.
Jest to elastyczność, która daje JS jego moc i testowania dla ciągów specjalnie czyni kod mniej interoperacyjne.
Wynikiem powyższego jest:
hEllo thErE hEllo thErE
Is string? true "hello there"
OH MY OH MY
Is string? true "oh my"
368 is a big number 368 is a big number
Is string? true "368"
56839 56839
Is string? true "😇"
0 0
Is string? true "10"
Chodzi o to, dlaczego chcesz wiedzieć, czy coś jest struną.
Jeśli, tak jak ja, przybyłeś tutaj z Google'a i chciałeś zobaczyć, czy coś jest w stylu sznurka , oto odpowiedź.
Nie jest nawet drogi, chyba że pracujesz z naprawdę długimi lub głęboko zagnieżdżonymi tablicami char.
Wynika to z faktu, że chodzi tu tylko o instrukcje if, żadne wywołania funkcji takie jak .toString()
.
Z wyjątkiem sytuacji, gdy próbujesz sprawdzić, czy tablica toString()
znaków z obiektami, które mają tylko znaki wielobajtowe, w takim przypadku nie ma innego sposobu sprawdzenia niż wykonanie łańcucha i policzenie znaków, które bajty tworzą odpowiednio
function duckyString(string, normalise, unacceptable) {
var type = null;
if (!unacceptable)
unacceptable = {};
if (string && !unacceptable.chars && unacceptable.to == null)
unacceptable.to = string.toString == Array.prototype.toString;
if (string == null)
;
//tests if `string` just is a string
else if (
!unacceptable.is &&
(typeof string == 'string' || string instanceof String)
)
type = 'is';
//tests if `string + ''` or `/./.test(string)` is valid
else if (
!unacceptable.to &&
string.toString && typeof string.toString == 'function' && string.toString != Object.prototype.toString
)
type = 'to';
//tests if `[...string]` is valid
else if (
!unacceptable.chars &&
(string.length > 0 || string.length == 0)
) {
type = 'chars';
//for each char
for (var index = 0; type && index < string.length; ++index) {
var char = string[index];
//efficiently get its length
var length = ((duckyString(char, false, {to:true})) ?
char :
duckyString(char, true) || {}
).length;
if (length == 1)
continue;
//unicode surrogate-pair support
char = duckyString(char, true);
length = String.prototype[Symbol && Symbol.iterator];
if (!(length = length && length.call(char)) || length.next().done || !length.next().done)
type = null;
}
}
//return true or false if they dont want to auto-convert to real string
if (!(type && normalise))
//return truthy or falsy with <type>/null if they want why it's true
return (normalise == null) ? type != null : type;
//perform conversion
switch (type) {
case 'is':
return string;
case 'to':
return string.toString();
case 'chars':
return Array.from(string).join('');
}
}
Zawarte są opcje do
.toString()
)Oto więcej testów, ponieważ jestem uzupełniaczem:
out('Edge-case testing')
function test(text, options) {
var result = duckyString(text, false, options);
text = duckyString(text, true, options);
out(result + ' ' + ((result) ? '"' + text + '"' : text));
}
test('');
test(null);
test(undefined);
test(0);
test({length:0});
test({'0':'!', length:'1'});
test({});
test(window);
test(false);
test(['hi']);
test(['\uD83D\uDE07']);
test([['1'], 2, new String(3)]);
test([['1'], 2, new String(3)], {chars:true});
Wynik:
Edge-case testing
is ""
null null
null null
to "0"
chars ""
chars "!"
null null
chars ""
to "false"
null null
chars "😇"
chars "123"
to "1,2,3"
Wystarczy, aby rozwinąć @ Drax za odpowiedź , chciałbym to zrobić:
function isWhitespaceEmptyString(str)
{
//RETURN:
// = 'true' if 'str' is empty string, null, undefined, or consists of white-spaces only
return str ? !(/\S/.test(str)) : (str === "" || str === null || str === undefined);
}
Uwzględnia także null
s i undefined
typy oraz zajmuje się typami nieciągłymi, takimi jak 0
.
To mi wystarczy.
OSTRZEŻENIE: To nie jest idealne rozwiązanie. Zobacz dół mojego postu.
Object.prototype.isString = function() { return false; };
String.prototype.isString = function() { return true; };
var isString = function(a) {
return (a !== null) && (a !== undefined) && a.isString();
};
I możesz użyć tego jak poniżej.
//return false
isString(null);
isString(void 0);
isString(-123);
isString(0);
isString(true);
isString(false);
isString([]);
isString({});
isString(function() {});
isString(0/0);
//return true
isString("");
isString(new String("ABC"));
OSTRZEŻENIE: Działa to niepoprawnie w przypadku:
//this is not a string
var obj = {
//but returns true lol
isString: function(){ return true; }
}
isString(obj) //should be false, but true
Możesz użyć tej funkcji do określenia rodzaju czegokolwiek:
var type = function(obj) {
return Object.prototype.toString.apply(obj).replace(/\[object (.+)\]/i, '$1').toLowerCase();
};
Aby sprawdzić, czy zmienna jest ciągiem:
type('my string') === 'string' //true
type(new String('my string')) === 'string' //true
type(`my string`) === 'string' //true
type(12345) === 'string' //false
type({}) === 'string' // false
Nie jestem pewien, czy masz na myśli wiedzieć, czy jest to typ string
niezależnie od jego zawartości, czy też jego zawartość jest liczbą lub łańcuchem, niezależnie od jego typu.
Aby wiedzieć, czy jego typ jest ciągiem, na to już odpowiedziano.
Ale żeby wiedzieć na podstawie jego zawartości, czy jest to ciąg znaków, czy liczba, użyłbym tego:
function isNumber(item) {
return (parseInt(item) + '') === item;
}
I dla niektórych przykładów:
isNumber(123); //true
isNumber('123'); //true
isNumber('123a');//false
isNumber(''); //false
/^\d+$/.test('123')
aby uniknąć zawiłości potencjalnych problemów z analizą)