Bir değişkenin JavaScript'te dize olup olmadığını kontrol edin


1741

Bir değişkenin JavaScript'te bir dize mi yoksa başka bir şey mi olduğunu nasıl belirleyebilirim?

Yanıtlar:


1691

typeofOperatörü kullanabilirsiniz :

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"

Bu web sayfasından örnek . (Örnek biraz değiştirildi).

Bu, ile oluşturulan dizelerde beklendiği gibi çalışmaz new String(), ancak bu nadiren kullanılır ve [1] [2] 'ye karşı önerilir . Arzu ederseniz bunları nasıl ele alacağınızla ilgili diğer cevaplara bakınız.


  1. Google JavaScript Stil Kılavuzu'nun asla ilkel nesne sarmalayıcıları kullanmadığını söyler .
  2. Douglas Crockford , ilkel nesne paketlerinin kullanımdan kaldırılmasını önerdi .

45
@ Wolfy87 Lütfen typeof stringValue komutunun "string" yerine "object" döndürebileceği bazı durumlar olduğunu unutmayın. Cevabım hakkındaki yorumları görün.
DRAX

163
Tercih ettiğim cevap. Buna karşı argüman, nesne sarılı dizeler için 'başarısız' olmasıdır new String('foo'), ancak bu önemli değildir çünkü nesne sarılı dizeler kullanmamanız gereken değersiz bir özelliktir. Google stil kılavuzu onları yasaklıyor , Douglas Crockford bunların kullanımdan kaldırılmasını istiyor ve hiçbir kütüphane bunları kullanmıyor. Var gibi davranın ve typeofkorkmadan kullanın .
Mark Amery


2
@DanielLe, çünkü prensipte ona karşı olduğu için değil, bazı sorunları düzelten bir değiştirme önerdi.
Vsevolod Golovanov

4
Eğer baş ağrısına neden oluyorsa,% 99,99 zaman kodunuzu doğru yapılandırmadınız. Bu, NaN'ın mevcut olması ve yaptığı şeyi yapması hatası değildir, bu, bir sonraki verimi sağlayabilecek kodla çalıştığınızda not etmeniz, öğrenmeniz ve aklınızda bulundurmanız gereken bir şeydir.
Mike 'Pomax' Kamermans

1907

İşte benim işime yarayan bu:

if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else

77
"MyVar instanceof String", "typeof myVar == 'string'" nin üstünde ve ötesinde bir şey yapıyor mu?
svth

81
hatırladım. JavaScript'te değişken dize türüne veya Dize sınıfı olan nesne türüne sahip olabilirsiniz (aynı şey - her ikisi de dizedir - ancak farklı şekilde tanımlanır) bu yüzden iki kez kontrol edilir.
DRAX

38
var somevar = new String ('somestring') console.log (someofar türünde) // object
Danubian Sailor

82
-1 çünkü instanceofbazı alışılmadık kodlama uygulamalarını takip etmedikçe buradaki kontrol anlamsız bir gürültüdür ve bu cevap ne yaptığını veya neden kullanabileceğinizi açıklamak için hiçbir şey yapmaz. İhtiyacınız olan tek neden, nesne sarılı dizeler kullanmanızdır, ancak nesne sarılı dizeler, hiç kimsenin kullanmadığı değersiz bir özelliktir ve Google ve Crockford, kötü uygulama olarak mahkumdur ( google-styleguide.googlecode.com/svn/ trunk /… , crockford.com/javascript/recommend.html ).
Mark Amery

79
Olası vakaları doğru şekilde işleyen katı kod yazmanın kaçınılması gereken bir şey olduğunu şiddetle kabul etmiyorum. Her ikisini de kontrol etmek typeofve instanceofkodunuzun başkaları tarafından aranabilmesi iyi bir tavsiye gibi geliyor. @ MarkAmery'nin postmessagekenar durumu, "ben sadece neydim postmessage?" - ancak bunun arayüzde ele alınmasını ve yayılmasına izin verilmemesini beklersiniz. Başka yerlerde, bazı JS estetleri bunları onaylamasa bile, kullanımdan kaldırılmamış kodlama yöntemlerini kullanmak doğru görünüyor. ASLA kodunuzu gerçekten kabul etmedikçe String'i kabul etmeyin!
Dewi Morgan

157

580+ kişi yanlış bir cevaba oy verdiğinden ve 800+ çalışan ama av tüfeği tarzı bir cevaba oy verdiğinden, cevabımı herkesin anlayabileceği daha basit bir biçimde tekrarlamaya değeceğini düşündüm.

function isString(x) {
  return Object.prototype.toString.call(x) === "[object String]"
}

Veya, satır içi (bunun için bir UltiSnip kurulum var):

Object.prototype.toString.call(myVar) === "[object String]"

Çünkü Bilginize, Pablo Santa Cruz cevap, yanlış typeof new String("string")olduğunuobject

DRAX'ın cevabı doğru ve işlevseldir ve doğru cevap olmalıdır (Pablo Santa Cruz kesinlikle yanlış olduğundan ve popüler oylamaya karşı çıkmayacağım.)

Bununla birlikte, bu cevap da kesinlikle doğrudur ve aslında en iyi cevaptır (belki de, lodash / alt çizgi kullanma önerisi hariç ). yasal uyarı: Lodash 4 kod tabanına katkıda bulundum.

Orijinal cevabım (açıkçası birçok kafa üzerinde uçtu):

Bunu underscore.js'den kod dönüştürdüm:

['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'].forEach( 
    function(name) { 
        window['is' + name] = function(obj) {
              return toString.call(obj) == '[object ' + name + ']';
    }; 
});

Bu isString, isNumber, vb.


Node.js'de bu bir modül olarak uygulanabilir:

module.exports = [
  'Arguments',
  'Function', 
  'String', 
  'Number', 
  'Date', 
  'RegExp'
].reduce( (obj, name) => {
  obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
  return obj;
}, {});

[değiştir]: Object.prototype.toString.call(x)işlevler ile eşzamansız işlevler arasında da sınırlama yapmaya çalışır:

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))


11
Underscore.js'yi öneriyorsunuz (hangi garip nedenden dolayı?) Ama burada kullanmıyorsunuz. Dahası, küresel isim alanını işlevlerle kirletiyorsunuz. Node.js size (bütün bu işlevleri olurdu bir modül oluşturmak istiyorum olabilir kullanmak global || windowyerine windowama bu ilk etapta olmamalıdır bir sorunu çözmek için kötü bir yaklaşım olacaktır).
Benjamin Gruenbaum

19
@BenjaminGruenbaum OP'nin sorusunun cevabını aramaya geldim ve cevapların hiçbirini beğenmedim. Bu yüzden alt çizgi ne yaptı kontrol ve biraz ayıklamak ve değiştirmek için yeterli olduğunu düşündüm (alt çizgi kitaplığı yüklü olması önlemek için). Gönderiyi netleştireceğim.
Orwellophile

2
@Orwellophile Cool, şimdi anladım, orijinal cevabınız altçizgi önerdiğiniz gibi ifade edildi. Şahsen ben sadece myObject+"" === myObjectbir nesnenin bir dize olup olmadığını kontrol etmek için kontrol (ya da daha iyisi, ben ilk etapta bir davranış odaklı tip sistemi kontrol yazmak olmaz).
Benjamin Gruenbaum

18
@Orwellophile, Bu
Pacerier

3
O yeniden tanımlamak mümkündür böylece JS, maymun yama destekler toStringiçinde Object.prototype. Bu nedenle, toStringbir nesnenin türünü kontrol etmeye güvenmenin en iyi ihtimalle kötü bir uygulama olduğunu iddia ediyorum .
Andre Rodrigues

84

Yerleşik işlevleri jQuery veya lodash / Underscore'dan kullanmanızı öneririm . Kullanımı daha basit ve okunması daha kolaydır.

Her iki işlev de belirtilen DRAX durumunu işleyecektir ... yani, ikisi de (A) değişkenin bir dize değişmezi mi yoksa (B) bu String nesnesinin bir örneği mi olduğunu kontrol eder. Her iki durumda da, bu işlevler değeri doğru olarak dize olarak tanımlar.

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

Daha fazla ayrıntı için _.isString () için lodash Belgelerine bakın.

Daha fazla bilgi için $ .type () için jQuery Belgeleri'ne bakın .


97
Bu JS topluluğunda neyin yanlış olduğunun temelidir - ilkel tipe karşı kontrol etmek tek astarlıdır ve sadece dil yapısını (temellerden biri) içerir, ancak harici kitaplık kullanmanızı öneririz. Birisi zaten bu kütüphanelerden birini kullanıyorsa, bu iyi bir fikir olabilir, ancak sadece türünü kontrol etmek yerine bunları indirmek sadece bir overkill'dir.
Rafał Wrzeszcz

5
Rafal ile hemfikir olacağım. Bu harici kütüphanelerden birini kullanmak için "okunabilirliği" geliştirdiği her yerde görüyorum. JavaScript biliyorsanız, okumadığınız bazı harici kitaplıklardan daha kolay okunur. _.every()ilk başta kullanmak biraz kafa karıştırıcı ve _.isBoolean()şirketimdeki geliştiricileri karıştırdığı kadar basit bir şey . Bir geliştirici, değerin bir boole ve yanlış olmasının yanlış olacağını düşündü. İngilizce benim için Almanca okumaktan daha kolay çünkü Almanca bilmiyorum. JavaScript öğrenin ve hepsi mantıklı olacaktır.
John Harding

20
@ RafałWrzeszcz Bu kütüphaneler oldukça yaygın olarak kullanılmaktadır ve çok kullanışlı (ve test edilmiş) işlevsellik sağlar. Özellikle lodash. Birisi sadece bu bir çözüm için kullanmak için kütüphane indir tavsiye etmem .... ama her javascript geliştirici bu kütüphaneyi indirmek ve ne eksik görmek bakın. ;)
ClearCloud8

13
Hepiniz Lodash gibi bir kütüphanenin noktasını kaçırıyorsunuz: hız değil. "Geliştirme kolaylığı" değil. Lodash gibi bir kütüphaneyi kullanmanın nedeni js uygulamanızı patlatacak sorunlara karşı "savunmasızlık" sağlar. Bir nesne üzerinde dize işlemleri yapmaya çalıştığınızda (ya da tam tersi) ölümcül hatalar meydana gelir ve Lodash bu hataları önlemede büyük bir değer sağlar.
random_user_name

1
Birçok kişinin bunu bir Düğüm veya Düğüm benzeri bir ortamda yapacağını ve çok az kişinin jQuery kullanacağını unutmayın.
Matt Fletcher

35
function isString (obj) {
  return (Object.prototype.toString.call(obj) === '[object String]');
}

Bunu burada gördüm:

http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/


4
Yanıtta verilen URL'de belirtildiği gibi çapraz çerçeve / çapraz pencere referans senaryolarını işlediğinden, bu çözümün en sağlam olduğunu düşünüyorum.
EWH

1
Harika cevap, Underscore.js de bu yöntemi kullanıyor gibi görünüyor!
Daan

1
@ling Sadece merak ediyorum, neden parantez koyuyorsun Object.prototype.toString.call(obj) === '[object String]'?
StubbornShowaGuy

@Earlee Daha (x === y)iyi okunabilirliğe sahip x === ymisiniz?
StubbornShowaGuy

@StubbornShowaGuy Bence evet. Aynı zamanda tutarlılık ile de ilgilidir. Şahsen her zaman bir değer döndürürken parantez kullanıyorum.
Aquarelle

28

En iyi yol:

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');

Bunların her biri, "new Object ()" vb. Gibi uygun sınıf işleviyle oluşturulmuştur.

Ayrıca, Duck-Typing: "Ördek gibi görünüyor, ördek gibi yürüyor ve ördek gibi kokuyor - bir dizi olmalı" Anlamı, özelliklerini kontrol edin.

Bu yardımcı olur umarım.

Düzenle; 2016/12/05

Unutmayın, her zaman yaklaşım kombinasyonlarını da kullanabilirsiniz. Aşağıda , typeof ile satır içi eylemler haritası kullanma örneği :

var type = { 'number': Math.sqrt.bind(Math), ... }[ typeof datum ];

Satır içi haritaları kullanmanın daha 'gerçek dünya' örneği:

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

Bu işlev, bir değişkenin gerçekten "var" olup olmadığını anlamak için [custom] "type-cast" (daha çok "type - / - value-mapping") kullanır. Şimdi bu kötü saçları null& arasında bölebilirsiniz 0!

Çoğu zaman türünü bile önemsemiyorsunuz . Yazmayı atlatmanın bir başka yolu da Duck-Type setlerini birleştirmektir:

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) ...;
}

Hem Number.prototype ve String.prototype bir var .toString() method. Sayının dize eşdeğerinin aynı olduğundan emin oldunuz ve sonra bunu httpa işlevine aktardığınızdan emin oldunuz Number. Başka bir deyişle, türünün ne olduğunu bile umursamadık .

Umarım çalışmak için daha fazlasını verir :)


Yapıcı özelliklerini almaya çalışmak başarısız olacağından, düz eski sayılar için başka bir kontrole ihtiyacınız olacaktır:

@ torazaburo Şu anda Chrome konsolunda benim için iyi çalıştı. Sizi işe yaramayacağını düşündüren nedir?
Mark Amery

2
@torazaburo İddialarla ( (o.constructor === Number || s.constructor === Boolean)) oynamak isteyebilirsiniz . Anekdot olarak parseIntve NaNkırılgan ancak güçlü araçlardır. Unutmayın, Sayı Değil Sayı Değildir ve tanımsız tanımlanabilir.
Cody

1
a.constructor === Dizi yanlış ve bazen başarısız olabilir, kullanım Array.isArray bkz web.mit.edu/jwalden/www/isArray.html
axkibe

1
Kabul etti, bu arıza güvenli değil. Daha iyi bir yol, mülk kontrollerini kullanmaktır - şu anda sadece gerçekten güvenli olan tek yol. Örnek: if(thing.call) { 'its a function'; }veya if(thing.defineProperties) { 'its an object'; }. Giriş için teşekkürler, axkibe!
Cody

17

Dürüst olmak gerekirse neden sadece typeofbu durumda kullanmak olmaz görüyorum :

if (typeof str === 'string') {
  return 42;
}

Evet, nesne sarılı dizelere (örneğin new String('foo')) karşı başarısız olacaktır, ancak bunlar yaygın olarak kötü bir uygulama olarak kabul edilir ve çoğu modern geliştirme aracı kullanımlarını caydırır. (Birini görürseniz, düzeltin!)

Object.prototype.toStringHüner tüm ön uç geliştiriciler kariyerlerinde bir gün yapmanın suçlu bulunmuş fakat zeki onun cila ile sizi aldatmasına izin vermeyin o taşıyor çünkü bir şey maymun yama Nesne prototip en kısa sürede kıracak:

const isString = thing => Object.prototype.toString.call(thing) === '[object String]';

console.log(isString('foo'));

Object.prototype.toString = () => 42;

console.log(isString('foo'));


15

Bu basit çözümü kullanmayı seviyorum:

var myString = "test";
if(myString.constructor === String)
{
     //It's a string
}

3
4 yıl sonra Cody'nin cevabından farkı nedir?
Jonathan H

3
@Sheljohn Cody'nin cevabı harika. Cevabım (tam metin) daha kısa ve doğrudan doğruya. Siz istediniz ... :)
ScottyG

Bir işlev olarak, bunun undefinedve ile başa çıkmanın nullve yine de boş dizeler ( ''ve hem de new String('')) için doğru cevabı almanın bir yolu gerekir .
MikeBeaton

@MikeBeaton Sorun: (mystring || false) && mystring.constructor === String. Bir boole döndürmesi gereken bir işlevde kullanılması durumunda false kullandım.
alans

13

Performansın neden önemli olduğuna dair harika bir örnek:

Doğru yapılmazsa, bir dize testi kadar basit bir şey yapmak pahalı olabilir.

Örneğin, bir şey bir dize olup olmadığını test etmek için bir işlev yazmak istedim, bunu iki yoldan biriyle yapabilirim:

1) const isString = str => (Object.prototype.toString.call(str) === '[object String]');

2) const isString = str => ((typeof str === 'string') || (str instanceof String));

Her ikisi de oldukça basittir, bu yüzden performansı ne etkileyebilir? Genel olarak, işlev çağrıları pahalı olabilir, özellikle de içinde ne olduğunu bilmiyorsanız. İlk örnekte, Object'in toString yöntemine bir işlev çağrısı gelir. İkinci örnekte, typeof ve instanceof işleçleri olduğu için işlev çağrısı yoktur. Operatörler, işlev çağrılarından önemli ölçüde daha hızlıdır.

Performans test edildiğinde, örnek 1, örnek 2'den% 79 daha yavaştır!

Testlere bakın: https://jsperf.com/isstringtype


Test linki öldü, ama sana inanıyorum. Bu tür bilgiler çok önemlidir. IMHO bu, en çok oylanan cevap olmasa da, mevcut lider cevap hakkında en azından en çok oylanan yorum olmalıdır.
Coderer

typeof str === 'string' || str instanceof String( if (..)durumlarda tercih ettiğim parantezi düşürebilir ); ne olursa olsun, # 2'deki ilkel ve nesne türlerinin kontrol edilmesi açık ve yeterlidir. Bu kontroller zaten 'nadir' olmalıdır.
user2864740

13
if (s && typeof s.valueOf() === "string") {
  // s is a string
}

Hem dize değişmezleri hem de let s = 'blah'Nesne Dizeleri için çalışırlet s = new String('blah')


3
Dikkat! Bu boş dizelerde başarısız olur, çünkü bunlar falseydir.
Philipp Sumi

8

Lodash'tan alınmıştır:

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


5

Bence @customcommander çözümü vakalarınızın% 90'ında yeterli olmalı:

typeof str === 'string'

Size doğru hizmet etmelidir (normalde new String('something')kodunuzda yer almak için hiçbir neden yoktur ).

StringNesneyi de ele almakla ilgileniyorsanız (örneğin, 3. bir taraftan bazı değişkenler bekliyorsunuz) o zaman @ ClearCloud8 önerdiği gibi lodash'ı kullanmak net, basit ve zarif bir çözüm gibi görünüyor.

Ancak boyutları nedeniyle lodash gibi kütüphanelere karşı dikkatli olmanızı öneririm. Yapmak yerine

import _ from 'lodash'
...
_.isString(myVar)

Hangi bütün büyük lodash nesnesini getiriyor, ben şöyle bir şey öneririm:

import { isString as _isString } from 'lodash'
...
_isString(myVar)

Ve basit demetleme ile iyi olmalısınız (burada müşteri koduna atıfta bulunuyorum).


neden === ne zaman == yeterli
zavr

4

Node.js ortamında çalışıyorsanız, yerleşik isString işlevini yardımcı programlarda kullanabilirsiniz.

const util = require('util');
if (util.isString(myVar)) {}

Düzenleme: @Jehy'nin belirttiği gibi, bu v4'ten beri kullanımdan kaldırıldı.


Değiştirme var mı?
Anthony Kong

3
Belgeler "Kullan typeof value === 'string'yerine " diyor .
Bay Rogers

x = new String('x'); x.isString(x);yanlış döndürür . Var util.types.isStringObject()ama bu x = 'x'tür string için false döndürür . Kesinlikle hiçbir yarar sağlamaz iki yarar fonksiyonları
spinkus

4

Aşağıdaki yöntem, herhangi bir değişkenin bir dize olup olmadığını kontrol eder ( var olmayan değişkenler dahil ).

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

3

Ayrıca bunun da iyi çalıştığını ve diğer örneklerden çok daha kısa olduğunu buldum.

if (myVar === myVar + '') {
   //its string
} else {
   //its something else
}

Boş tırnak işaretlerini birleştirerek değeri bir dizeye dönüştürür. Eğer myVarzaten ifadesi başarılı olursa o zaman bir dizedir.


3
Tek sorun, değişkenini kontrol etmek istediğinizde bir değişkeni zorlamanızdır. Bu bana göre biraz pahalı görünüyor typeof.
Olical

1
Evet, haklısın. jsperf bunun yaklaşık% 20 daha yavaş olduğunu, typeofancak yine de biraz daha hızlı olduğunu söyledi toString. Her iki durumda da sanırım zorlama sözdizimini seviyorum.
Chris Dolphin

4
bu String tipi ile çalışmaz; var s = new String('abc'); > s === s + '' > false
user5672998

1
new StringBir tür oluşturan cus ile çalışmaz object. w3schools.com/js/tryit.asp?filename=tryjs_string_object2
Chris Dolphin

İyi düşünülmüş, ancak nesne sarılmış dizelerin kenar durumunu dışarı bırakır.
Anthony Rutledge

3
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))

X.constructor === Dize de null veya undefined için false değerini döndürürse neden null veya undefined olup olmadığını denetlemeniz gerekiyor?
Jules Manson

1
@JulesManson: Üretmek değil, hata verir false.
Ry-

3

Ben tip-onay için yararlıdır bu basit tekniği bulmak dize -

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

Aynı teknik Sayı için de geçerlidir -

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

Ve RegExp için -

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

Nesne için Aynı -

Object(x) === x // true, if x is an object
                // false in every other case

NB, normal ifadeler, diziler ve işlevler de nesne olarak kabul edilir.

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)    

Ama, kontrol Array biraz farklı -

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

Bu teknik geliyor değil çalışmak Fonksiyonlar ancak -

Function(x) === x // always false

var x = new String(x); String(x)===xyanlış döndürür. Ancak ({}).toString.call(x).search(/String/)>0her zaman telli şeyler için döner
senkronize olmayan

1
function isClass(x,re){return ({}).toString.call(x).search(re)>0;}; isClass("hello",/String/) veya isClass(3,/Number/)veyaisClass(null,/Null/)
senkronize edilmemiş

2

Basit bir çözüm:

var x = "hello"

if(x === x.toString()){
// it's a string 
}else{
// it isn't
}

1
bu bir dize olup olmadığını kontrol etmez . Bir ip haline gelir, birçok şeyin toString()işlevi vardır
Muhammed Umer

7
@MuhammadUmer Evet, bunu bir dizeye dönüştürür, ancak orijinal değere göre kimlik olup olmadığını denetler; bu yalnızca orijinal değer de bir dize olduğunda Doğru olur.
MrWhite

4
bu yanlış: .toStringherhangi bir değeri körü körüne çağıramazsınız ; kontrol edilecek x boş veya tanımsızsa, kod atma istisnası varsa deneyin
user5672998

1
Fikir hala kullanılabilir. x === Dize (x) güvenlidir ve çalışır.
Márton Sári

Gerçekten mi? Bu çözüm benim için çok garip görünüyor, çünkü toString()yöntem geçersiz kılınabilir ve bir istisna atabilir (bazı belirli uygulamalar nedeniyle) ve çekiniz kesin olarak çalışmayacaktır. Ana fikir, almak istediğinizle ilgili olmayan yöntemleri çağırmamalısınız. toStringYöntemle ilgili gereksiz yükten bile bahsetmiyorum . Downvoting.
Rustem Zinnatullin

2

Bir Typechecker yardımcısı:

function isFromType(variable, type){
  if (typeof type == 'string') res = (typeof variable == type.toLowerCase())
  else res = (variable.constructor == type)
  return res
}

kullanımı:

isFromType('cs', 'string') //true
isFromType('cs', String) //true
isFromType(['cs'], Array) //true
isFromType(['cs'], 'object') //false

Eğer özyinelemeli olmak istiyorum Ayrıca eğer (bir nesne olduğu istasyonu gibi), kullanabilirsiniz instanceof.

( ['cs'] instanceof Object //true)


2

Burada bir değişkenin belirli bir türün mü yoksa belirli bir kümenin üyesi mi olduğunu söylemeye çalışan farklı bir rotaya gideceğim.
JS ördek yavrusu üzerine kuruludur; bir şey bir dize gibi quacks, biz bir dize gibi kullanabilirsiniz ve kullanmalıyız.

7bir dize? Öyleyse neden /\d/.test(7)çalışıyor?
{toString:()=>('hello there')}bir dize? Öyleyse neden ({toString:()=>('hello there')}) + '\ngeneral kenobi!'çalışıyor?
Bunlar hakkında sorular değil should yukarıdaki iş, nokta yaptıklarını olduğunu.

Bu yüzden bir duckyString()fonksiyon yaptım
Aşağıda, diğer cevaplar tarafından karşılanmayan birçok vakayı test ediyorum. Her kod için:

  • dize benzeri bir değişken ayarlar
  • üzerinde özdeş bir dize işlemi ve çıktıları karşılaştırmak için gerçek bir dize çalıştırır (dize gibi davranılabileceğini kanıtlar)
  • duckyString()gerçek dizeleri bekleyen kod girişlerini normalleştirmenizi göstermek için dize benzeri bir gerçek dize dönüştürür
text = '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');

Gibi bu aynı etkiye sahiptir !!xaksine x===truebir şey array- ise ve test gibi yerine, gerçek bir dizi gerektirecek bir.
jQuery nesneleri; diziler mi? Hayır. Yeterince iyi mi? Evet, onları Array.prototypeiyi fonksiyonlarla çalıştırabilirsiniz .
Onun gücünü JS ve test verir bu esneklik var için dizeleri özellikle kodunuzu daha az çalışabilir hale getirir.

Yukarıdakilerin çıktısı:

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"

Yani, neden bir şeyin bir ip olup olmadığını bilmek istediğinizle ilgilidir.
Benim gibi, Google'dan buraya geldiyseniz ve bir şeyin ip gibi olup olmadığını görmek istediyseniz , işte bir cevap.
Gerçekten uzun veya derin yuvalanmış karakter dizileriyle çalışmadığınız sürece bile pahalı değildir.
Bunun nedeni, eğer ifadelerin hepsi, hiçbir işlev çağırmazsa olmasıdır .toString().
Yalnızca toString()veya çok baytlık karakterleri olan nesnelerin bulunduğu bir char dizisinin olup olmadığını görmeye çalışıyorsanız , bu durumda dizeyi yapmak ve baytların oluşturduğu karakterleri saymak dışında kontrol etmenin başka bir yolu yoktur.

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('');
    }
}

Dahil seçenekler şunlardır

  • hangi yöntemin string-y saydığını sor
  • dize algılama yöntemlerini hariç tutma (örneğin, beğenmiyorsanız .toString())

İşte daha fazla test, çünkü ben bir tamamlayıcıyım:

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});
  • Tüm olumsuz vakalar açıklanmaktadır
  • Bu, tarayıcılarda çalışmalıdır> = IE8
  • Dize yineleyici desteğine sahip tarayıcılarda desteklenen birden çok baytlı karakter dizileri

Çıktı:

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"

1

@ DRAX'ın cevabını genişletmek için şunu yapardım :

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);
}

Ayrıca nulls ve undefinedtürleri de hesaba katar ve dize olmayan türlerle ilgilenir 0.


1

Bu benim için yeterince iyi.

UYARI: Bu mükemmel bir çözüm değildir. Yazımın altına bakın.

Object.prototype.isString = function() { return false; };
String.prototype.isString = function() { return true; };

var isString = function(a) {
  return (a !== null) && (a !== undefined) && a.isString();
};

Ve bunu aşağıdaki gibi kullanabilirsiniz.

//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"));

UYARI: Bu, aşağıdaki durumlarda yanlış çalışır:

//this is not a string
var obj = {
    //but returns true lol
    isString: function(){ return true; }
}

isString(obj) //should be false, but true

-1

Herhangi bir şeyin türünü belirlemek için bu işlevi kullanabilirsiniz:

var type = function(obj) {
    return Object.prototype.toString.apply(obj).replace(/\[object (.+)\]/i, '$1').toLowerCase();
};

Bir değişkenin dize olup olmadığını kontrol etmek için:

type('my string') === 'string' //true
type(new String('my string')) === 'string' //true
type(`my string`) === 'string' //true
type(12345) === 'string' //false
type({}) === 'string' // false

https://codepen.io/patodiblasi/pen/NQXPwY?editors=0012


-2

stringİçeriğinden bağımsız olarak bir tür olup olmadığını veya türüne bakılmaksızın içeriğinin bir sayı veya dize olup olmadığını bilmek istediğinizden emin değilim .

Bu yüzden türünün bir dize olup olmadığını bilmek için, zaten cevaplanmıştır.
Ama onun içeriği bir dize veya bir sayı olup olmadığını bilmek için, ben bunu kullanmak:

function isNumber(item) {
    return (parseInt(item) + '') === item;
}

Ve bazı örnekler için:

isNumber(123);   //true
isNumber('123'); //true
isNumber('123a');//false
isNumber('');    //false

Ben aslında o zaman nasıl soru bile oluşturacağını bilmiyordum rağmen, ben aslında, tür kontrol nasıl soruyordum düşünüyorum. (ve muhtemelen /^\d+$/.test('123')potansiyel ayrıştırma sorunlarının karışıklıklarından kaçınmak için bunu
yapardım
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.