Periksa apakah variabel adalah string dalam JavaScript

1742

Bagaimana saya bisa menentukan apakah suatu variabel adalah string atau sesuatu yang lain dalam JavaScript?

Olical
sumber

Jawaban:

1692

Anda dapat menggunakan typeofoperator:

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"

Contoh dari halaman web ini . (Contoh sedikit dimodifikasi).

Ini tidak akan berfungsi seperti yang diharapkan dalam kasus string yang dibuat dengan new String(), tetapi ini jarang digunakan dan direkomendasikan terhadap [1] [2] . Lihat jawaban lain untuk cara menanganinya, jika diinginkan.


  1. Panduan Gaya Google JavaScript mengatakan untuk tidak pernah menggunakan pembungkus objek primitif .
  2. Douglas Crockford merekomendasikan agar pembungkus objek primitif tidak digunakan lagi .
Pablo Santa Cruz
sumber
45
@ Wolfy87 Harap diperhatikan bahwa ada beberapa kasus bahwa typeof stringValue mungkin mengembalikan "objek" daripada "string". Lihat komentar pada jawaban saya.
DRAX
163
Jawaban pilihan saya. Argumen menentangnya adalah bahwa ia 'gagal' untuk string yang dibungkus objek seperti new String('foo'), tetapi itu tidak masalah karena string yang dibungkus objek adalah fitur yang tidak berharga yang tidak boleh Anda gunakan. Panduan gaya Google melarang mereka , Douglas Crockford menginginkannya tidak digunakan lagi , dan tidak ada perpustakaan yang menggunakannya. Berpura-pura mereka tidak ada, dan gunakan typeoftanpa rasa takut.
Mark Amery
2
@DanielLe, karena dia mengusulkan pengganti yang memperbaiki beberapa masalah, bukan karena dia menentangnya secara prinsip.
Vsevolod Golovanov
4
Jika itu menyebabkan Anda sakit kepala, 99,99% dari waktu itu karena Anda tidak menyusun kode dengan benar. Itu bukan kesalahan NaN untuk ada dan melakukan apa yang dilakukannya, itu adalah sesuatu yang harus Anda perhatikan, pelajari, dan ingatlah saat berikutnya Anda bekerja dengan kode yang mungkin menghasilkannya.
Mike 'Pomax' Kamermans
1909

Inilah yang bekerja untuk saya:

if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
DRAX
sumber
77
Apakah "myVar instanceof String" melakukan apa pun di atas dan di luar "typeof myVar == 'string'"?
svth
81
@svth saya ingat. Dalam JavaScript Anda dapat memiliki tipe variabel string atau tipe objek yang merupakan kelas String (hal yang sama - keduanya adalah string - tetapi didefinisikan secara berbeda) itulah sebabnya mengapa diperiksa ulang.
DRAX
38
var somevar = new String ('somestring') console.log (typeof somevar) // objek
Danubian Sailor
82
-1 karena instanceofcentang di sini adalah kebisingan yang tidak ada gunanya kecuali Anda mengikuti beberapa praktik pengkodean yang sangat tidak biasa , dan jawaban ini tidak menjelaskan apa yang dilakukannya atau mengapa Anda menggunakannya. Satu-satunya alasan Anda membutuhkannya adalah jika Anda menggunakan string yang dibungkus objek, tetapi string yang dibungkus objek adalah fitur yang tidak berharga yang tidak digunakan oleh siapa pun dan Google dan Crockford keduanya mengutuk sebagai praktik yang buruk ( google-styleguide.googlecode.com/svn/ trunk / ... , crockford.com/javascript/recommend.html ).
Mark Amery
79
Saya sangat tidak setuju bahwa menulis kode padat yang benar menangani kasus yang tidak mungkin adalah sesuatu yang harus dihindari. Memeriksa keduanya typeofdan instanceofterasa seperti saran yang bagus jika kode Anda dapat dipanggil oleh orang lain. @ Kasus postmessagetepi MarkAmery penting jika Anda bertanya "apa yang baru saja aku lakukan postmessage?" - tetapi Anda berharap itu ditangani di antarmuka dan tidak diizinkan untuk diperbanyak. Di tempat lain, tampaknya benar untuk menangani metode pengkodean yang tidak usang bahkan jika beberapa JS aesthetes tidak menyetujuinya. TIDAK PERNAH mengomentari kode Anda sebagai menerima String, kecuali jika benar-benar melakukannya!
Dewi Morgan
157

Karena 580+ orang telah memilih jawaban yang salah, dan 800+ telah memilih jawaban yang berfungsi tetapi bergaya senapan, saya pikir mungkin layak untuk mengulang jawaban saya dalam bentuk yang lebih sederhana yang dapat dipahami semua orang.

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

Atau, inline (Saya memiliki pengaturan UltiSnip untuk ini):

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

FYI, jawaban Pablo Santa Cruz salah, karena typeof new String("string")memang begituobject

Jawaban DRAX akurat dan fungsional, dan seharusnya menjadi jawaban yang benar (karena Pablo Santa Cruz jelas salah, dan saya tidak akan berdebat menentang pemilihan umum).

Namun, jawaban ini juga pasti benar, dan sebenarnya jawaban terbaik (kecuali, mungkin, untuk saran menggunakan lodash / garis bawah ). disclaimer: Saya berkontribusi pada basis kode lodash 4.

Jawaban asli saya (yang jelas terbang tepat di atas banyak kepala) berikut:

Saya mentranskode ini dari underscore.js:

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

Itu akan menentukan isString, isNumber, dll.


Di Node.js, ini bisa diimplementasikan sebagai modul:

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

[sunting]: Object.prototype.toString.call(x)berfungsi untuk menggambarkan antara fungsi dan fungsi asink juga:

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

Orwellophile
sumber
11
Anda merekomendasikan underscore.js (untuk alasan aneh apa?) Tetapi Anda tidak menggunakannya di sini. Apalagi Anda mencemari namespace global dengan fungsi. Di node.js Anda akan membuat modul yang memiliki semua fungsi-fungsi ini (Anda dapat menggunakan global || windowalih-alih windowtetapi itu akan menjadi pendekatan yang buruk untuk memecahkan masalah yang seharusnya tidak Anda miliki di tempat pertama).
Benjamin Gruenbaum
19
@BenjaminGruenbaum Saya datang mencari jawaban untuk pertanyaan OP, dan tidak menyukai jawaban apa pun. Jadi saya memeriksa apa yang garis bawah lakukan, dan berpikir itu cukup bagus untuk mengekstrak dan memodifikasi sedikit (untuk menghindari keharusan memiliki perpustakaan garis bawah dimuat). Saya akan mengklarifikasi posting saya.
Orwellophile
2
@Orwellophile Keren, saya mengerti sekarang, jawaban asli Anda diutarakan seperti Anda menyarankan garis bawah sendiri. Secara pribadi saya hanya akan memeriksa myObject+"" === myObjectuntuk memeriksa apakah suatu objek adalah string (atau bahkan lebih baik, saya tidak akan mengetikkan check-in dalam sistem tipe driven perilaku di tempat pertama).
Benjamin Gruenbaum
18
@Orwellophile, Bagaimana ini lebih baik dari jawaban DRAX?
Pacerier
3
JS mendukung tambalan monyet, jadi dimungkinkan untuk mendefinisikan ulang toStringdi Object.prototype. Jadi, saya berpendapat bahwa mengandalkan toStringmemeriksa jenis objek, paling tidak, merupakan praktik yang buruk.
Andre Rodrigues
84

Saya sarankan menggunakan fungsi bawaan dari jQuery atau lodash / Underscore . Mereka lebih mudah digunakan dan lebih mudah dibaca.

Salah satu fungsi akan menangani kasus DRAX yang disebutkan ... yaitu, mereka berdua memeriksa apakah (A) variabel tersebut adalah string literal atau (B) itu adalah turunan dari objek String. Dalam kedua kasus, fungsi-fungsi ini dengan benar mengidentifikasi nilai sebagai string.

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

Lihat Dokumentasi lodash untuk _.isString () untuk lebih jelasnya.

Lihat Dokumentasi jQuery untuk $ .type () untuk detail lebih lanjut.

ClearCloud8
sumber
97
Ini adalah hal mendasar dari apa yang salah dengan komunitas JS - memeriksa terhadap tipe primitif adalah satu-baris dan melibatkan konstruksi bahasa yang adil (salah satu dasar), tetapi Anda merekomendasikan menggunakan perpustakaan eksternal. Jika seseorang sudah menggunakan salah satu dari pustaka ini mungkin ide yang bagus, tetapi mengunduhnya hanya untuk itu dan bukan hanya memeriksa jenisnya adalah kerja keras.
Rafał Wrzeszcz
5
Saya akan setuju dengan Rafal. Saya melihat di mana-mana bahwa itu meningkatkan "keterbacaan" untuk menggunakan salah satu perpustakaan eksternal ini. Jika Anda tahu JavaScript, maka itu lebih mudah dibaca daripada perpustakaan eksternal yang belum Anda gunakan. _.every()sedikit membingungkan untuk digunakan pada awalnya, dan sesuatu yang sederhana seperti _.isBoolean()devs bingung di perusahaan saya. Seorang dev keliru berpikir itu akan salah jika nilainya boolean dan salah. Bahasa Inggris lebih mudah dibaca daripada bahasa Jerman untuk saya, karena saya tidak tahu bahasa Jerman. Pelajari JavaScript dan itu semua masuk akal.
John Harding
20
@ RafałWrzeszcz Perpustakaan ini cukup banyak digunakan dan menyediakan fungsionalitas yang bermanfaat (dan teruji). Terutama lodash. Saya tidak akan merekomendasikan seseorang mengunduh perpustakaan hanya untuk digunakan untuk solusi yang satu ini .... tapi saya akan merekomendasikan setiap pengembang javascript mengunduh perpustakaan ini dan melihat apa yang mereka lewatkan. ;)
ClearCloud8
13
Semua kalian kehilangan titik perpustakaan seperti Lodash: bukan kecepatan. Bukan "kemudahan pengembangan". Alasan untuk menggunakan perpustakaan seperti Lodash memberikan "pertahanan" terhadap masalah yang akan meledakkan aplikasi js Anda. Kesalahan fatal terjadi ketika Anda mencoba melakukan operasi string pada suatu objek (atau sebaliknya), dan Lodash memberikan nilai luar biasa untuk mencegah kesalahan tersebut.
random_user_name
1
Ingatlah bahwa banyak orang akan melakukan ini di lingkungan Node atau mirip Node, dan sangat sedikit orang akan menggunakan jQuery di sana.
Matt Fletcher
35
function isString (obj) {
  return (Object.prototype.toString.call(obj) === '[object String]');
}

Saya melihat itu di sini:

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

ling
sumber
4
Saya pikir solusi ini adalah yang paling kuat karena menangani skenario referensi cross-frame / cross-window seperti yang disebutkan dalam URL yang disediakan dalam jawaban.
ewh
1
Jawaban bagus, sepertinya Underscore.js juga menggunakan metode ini!
Daan
1
@ling Hanya ingin tahu, mengapa Anda menaruh tanda kurung Object.prototype.toString.call(obj) === '[object String]'?
StubbornShowaGuy
@ Earlee Maksud Anda (x === y)memiliki keterbacaan yang lebih baik daripada x === y?
StubbornShowaGuy
@StubbornShowaGuy Menurut pendapat saya, ya. Ini juga tentang konsistensi. Saya pribadi selalu menggunakan tanda kurung ketika mengembalikan nilai.
Aquarelle
28

Cara terbaik:

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

Masing-masing telah dibangun oleh fungsi kelas yang sesuai, seperti "Objek baru ()" dll.

Juga, Bebek Mengetik: "Jika itu terlihat seperti bebek, berjalan seperti bebek, dan baunya seperti bebek - itu pasti sebuah Array" Artinya, periksa propertinya.

Semoga ini membantu.

Edit; 12/05/2016

Ingat, Anda selalu dapat menggunakan kombinasi pendekatan juga. Berikut adalah contoh menggunakan peta tindakan inline dengan typeof :

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

Berikut contoh yang lebih 'dunia nyata' dalam menggunakan inline-maps:

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

Fungsi ini akan menggunakan [custom] "type-casting" - lebih tepatnya, "type - / - value-mapping" - untuk mengetahui apakah suatu variabel benar-benar "ada". Sekarang Anda dapat memisahkan rambut jahat antara null& 0!

Sering kali Anda bahkan tidak peduli dengan tipenya . Cara lain untuk menghindari pengetikan adalah menggabungkan set Duck-Type:

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

Keduanya Number.prototype dan String.prototype memiliki .toString() method. Anda hanya memastikan bahwa string-setara dengan nomor itu sama, dan kemudian Anda memastikan bahwa Anda meneruskannya ke dalam httpfungsi sebagai a Number. Dengan kata lain, kami bahkan tidak peduli apa jenisnya.

Harapan yang memberi Anda lebih banyak untuk dikerjakan :)

Cody
sumber
Anda akan memerlukan beberapa pemeriksaan lain untuk nomor lama biasa, karena mencoba mengambil properti konstruktor mereka akan gagal:
@torazaburo Bekerja dengan baik untuk saya sekarang di konsol Chrome. Apa yang membuatmu berpikir itu tidak akan berhasil?
Mark Amery
2
@torazaburo Anda mungkin ingin bermain dengan pernyataan ( (o.constructor === Number || s.constructor === Boolean)). Secara anekdot, parseIntdan NaNmerupakan alat yang rapuh tetapi kuat. Ingat saja, Not-a-Number TIDAK NOT-a-Number, dan undefined dapat didefinisikan.
Cody
1
a.constructor === Array adalah salah dan bisa gagal kadang-kadang, penggunaan Array.isArray melihat web.mit.edu/jwalden/www/isArray.html
axkibe
1
Setuju, ini tidak aman-gagal. Cara yang lebih baik adalah dengan menggunakan pemeriksaan properti - ITULAH satu-satunya cara yang benar-benar aman untuk saat ini. Contoh: if(thing.call) { 'its a function'; }atau if(thing.defineProperties) { 'its an object'; }. Terima kasih atas masukannya, axkibe!
Cody
17

Jujur saya tidak bisa melihat mengapa orang tidak akan hanya menggunakan typeofdalam kasus ini:

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

Ya itu akan gagal terhadap string yang dibungkus objek (misalnya new String('foo')) tetapi ini secara luas dianggap sebagai praktik yang buruk dan sebagian besar alat pengembangan modern cenderung untuk mencegah penggunaannya. (Jika Anda melihatnya, perbaiki saja!)

The Object.prototype.toStringtrick adalah sesuatu yang semua pengembang front-end telah ditemukan bersalah melakukan satu hari dalam karir mereka tapi jangan biarkan hal itu menipu Anda dengan cat nya pintar: itu akan pecah secepat sesuatu monyet-patch Obyek prototipe:

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

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

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

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

customcommander
sumber
15

Saya suka menggunakan solusi sederhana ini:

var myString = "test";
if(myString.constructor === String)
{
     //It's a string
}
ScottyG
sumber
3
Apa bedanya dengan jawaban Cody, 4 tahun kemudian?
Jonathan H
3
@Sheljohn Cody jawabannya bagus. Jawaban saya (teks lengkap) lebih pendek dan langsung ke intinya. Anda bertanya ... :)
ScottyG
Sebagai fungsi, ini akan membutuhkan cara untuk menangani undefineddan null, dan masih mendapatkan jawaban yang tepat untuk string kosong (keduanya ''dan new String('')).
MikeBeaton
@MikeBeaton ada masalah: (mystring || false) && mystring.constructor === String. Saya menggunakan false jika digunakan dalam fungsi yang harus mengembalikan boolean.
alans
13

Ini adalah contoh bagus mengapa kinerja penting:

Melakukan sesuatu yang sederhana seperti tes untuk sebuah string bisa mahal jika tidak dilakukan dengan benar.

Misalnya, jika saya ingin menulis fungsi untuk menguji apakah ada sesuatu yang berupa string, saya bisa melakukannya dengan salah satu dari dua cara:

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

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

Kedua hal ini sangat lurus ke depan, jadi apa yang bisa berdampak pada kinerja? Secara umum, panggilan fungsi bisa mahal, terutama jika Anda tidak tahu apa yang terjadi di dalam. Pada contoh pertama, ada pemanggilan fungsi ke metode toString Object. Dalam contoh kedua, tidak ada panggilan fungsi, karena typeof dan instanceof adalah operator. Operator jauh lebih cepat daripada panggilan fungsi.

Ketika kinerja diuji, contoh 1 adalah 79% lebih lambat dari contoh 2!

Lihat tes: https://jsperf.com/isstringtype

Rob Brander
sumber
Tautan uji sudah mati, tapi saya percaya Anda. Informasi seperti ini sangat penting. IMHO ini seharusnya, jika bukan jawaban yang paling banyak dipilih, setidaknya komentar paling banyak tentang jawaban terkemuka saat ini.
Coderer
typeof str === 'string' || str instanceof String(dapat menghapus tanda kurung yang saya sukai dalam if (..)kasus); bagaimanapun, memeriksa baik tipe primitif dan objek dalam # 2 jelas dan memadai. Pemeriksaan ini harus 'jarang'.
user2864740
13
if (s && typeof s.valueOf() === "string") {
  // s is a string
}

Berfungsi untuk string literal let s = 'blah'dan untuk Object Stringslet s = new String('blah')

pembuat roda
sumber
3
Perhatian! Ini akan gagal pada string kosong, karena itu adalah falsey.
Philipp Sumi
8

Diambil dari 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
Benj Sicam
sumber
Jika seseorang ingin mengetahui sumbernya, itu adalah github.com/lodash/lodash/blob/master/isString.js
Ricardo Canelas
5

Saya pikir solusi @customcommander harus mencukupi dalam 90% kasus Anda:

typeof str === 'string'

Harus melayani Anda dengan benar (hanya karena biasanya tidak ada alasan untuk ada new String('something')dalam kode Anda).

Jika Anda tertarik untuk menangani Stringobjek juga (misalnya Anda mengharapkan beberapa var dari pihak ke-3) kemudian menggunakan lodash seperti yang disarankan @ ClearCloud8 tampaknya seperti solusi yang jelas, sederhana dan elegan.

Namun saya menyarankan untuk berhati-hati dengan perpustakaan seperti lodash karena ukurannya. Alih-alih melakukan

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

Yang membawa seluruh objek lodash besar, saya sarankan sesuatu seperti:

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

Dan dengan bundling sederhana Anda harus baik-baik saja (saya merujuk di sini ke kode klien).

Erez Cohen
sumber
mengapa === ketika == sudah cukup
zavr
4

Jika Anda bekerja di lingkungan node.js, Anda cukup menggunakan fungsi built-in isString di utils.

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

Sunting: seperti yang disebutkan @Jehy, ini sudah tidak digunakan lagi sejak v4.

David
sumber
Apakah ada penggantinya?
Anthony Kong
3
Dokumen mengatakan "Gunakan typeof value === 'string'saja."
Tuan Rogers
x = new String('x'); x.isString(x);mengembalikan salah . Ada util.types.isStringObject()tapi itu mengembalikan false untuk x = 'x'tipe string. Dua fungsi utilitas yang sama sekali tidak menyediakan utilitas ...
spinkus
4

Metode berikut akan memeriksa apakah ada variabel yang berupa string ( termasuk variabel yang tidak ada ).

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
Grant Miller
sumber
3

Saya juga menemukan bahwa ini berfungsi dengan baik juga, dan jauh lebih pendek daripada contoh lainnya.

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

Dengan menggabungkan pada kutipan kosong itu mengubah nilai menjadi string. Jika myVarsudah menjadi string maka pernyataan if berhasil.

Chris Dolphin
sumber
3
Satu-satunya masalah adalah Anda memaksa variabel ketika Anda ingin memeriksa tipenya. Sepertinya itu agak mahal bagi saya jika dibandingkan dengan typeof.
Olical
1
Jadi kamu benar. jsperf mengatakan sekitar 20% lebih lambat dari pada typeoftetapi masih sedikit lebih cepat dari toString. Either way, saya kira saya hanya suka sintaksis untuk paksaan.
Chris Dolphin
4
ini tidak berfungsi dengan tipe String; var s = new String('abc'); > s === s + '' > false
user5672998
1
Tidak bekerja dengan new Stringcus yang menciptakan tipe object. w3schools.com/js/tryit.asp?filename=tryjs_string_object2
Chris Dolphin
Pemikiran yang bagus, tetapi meninggalkan tepi case dari string yang dibungkus objek.
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))
Jake
sumber
Mengapa Anda perlu memeriksa null atau undefined jika x.constructor === String juga akan mengembalikan false untuk null atau undefined?
Jules Manson
1
@ JulesManson: Itu akan melempar kesalahan, bukan menghasilkan false.
Ry-
3

Saya menemukan teknik sederhana ini berguna untuk mengetik-periksa 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

Teknik yang sama juga berfungsi untuk Angka -

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

Dan untuk 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

Sama untuk Objek -

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

NB, regexps, array, dan fungsi juga dianggap objek.

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)    

Tapi, memeriksa Array agak berbeda -

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

Namun teknik ini tidak berfungsi untuk Fungsi -

Function(x) === x // always false
Terima kasih
sumber
var x = new String(x); String(x)===xmengembalikan salah. namun ({}).toString.call(x).search(/String/)>0selalu kembali untuk hal
tidak disinkronkan
1
function isClass(x,re){return ({}).toString.call(x).search(re)>0;}; isClass("hello",/String/) atau isClass(3,/Number/)atauisClass(null,/Null/)
tidak disinkronkan
2

Solusi sederhana adalah:

var x = "hello"

if(x === x.toString()){
// it's a string 
}else{
// it isn't
}
Noris
sumber
1
ini tidak memeriksa apakah ini sebuah string. Itu menjadi string, banyak hal yang toString()berfungsi
Muhammad Umer
7
@MuhammadUmer Ya, itu mengubahnya menjadi string tetapi kemudian memeriksa identitas terhadap nilai asli, yang hanya akan Benar jika nilai asli juga merupakan string.
MrWhite
4
ini salah: Anda tidak bisa secara buta memanggil .toStringnilai apa pun; coba jika x yang akan diperiksa adalah nol atau tidak terdefinisi, pengecualian melempar kode Anda
user5672998
1
Idenya masih bisa digunakan. x === String (x) aman dan berfungsi.
Márton Sári
Betulkah? Solusi ini tampaknya terlalu aneh bagi saya, karena toString()metode mungkin ditimpa dan dapat menimbulkan pengecualian (karena beberapa implementasi tertentu), dan cek Anda tidak akan bekerja dengan pasti. Gagasan utama adalah bahwa Anda tidak boleh memanggil metode yang tidak terkait dengan apa yang ingin Anda dapatkan. Saya bahkan tidak berbicara tentang overhead yang tidak perlu terkait dengan toStringmetode ini. Downvoting.
Rustem Zinnatullin
2

Seorang pembantu Typechecker:

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

pemakaian:

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

Juga jika Anda ingin menjadi rekursif (seperti Array yang merupakan Obyek), Anda dapat menggunakan instanceof.

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

yaya
sumber
2

Saya akan pergi ke rute yang berbeda ke yang lain di sini, yang mencoba untuk mengetahui apakah suatu variabel adalah spesifik, atau anggota dari set tertentu, jenis.
JS dibangun di atas ducktyping; jika sesuatu berdetak seperti string, kita bisa dan harus menggunakannya seperti string.

Apakah 7sebuah string? Lalu mengapa /\d/.test(7)berhasil?
Apakah {toString:()=>('hello there')}sebuah string? Lalu mengapa ({toString:()=>('hello there')}) + '\ngeneral kenobi!'berhasil?
Ini bukan pertanyaan tentang apakah pekerjaan di atas, intinya adalah mereka melakukannya.

Jadi saya membuat duckyString()fungsi
Di bawah ini saya menguji banyak kasus yang tidak dipenuhi oleh jawaban lain. Untuk setiap kode:

  • menetapkan variabel seperti string
  • menjalankan operasi string yang identik di atasnya dan string nyata untuk membandingkan output (membuktikan bahwa mereka dapat diperlakukan seperti string)
  • mengonversi string-like menjadi string nyata untuk menunjukkan duckyString()kepada Anda untuk menormalkan input untuk kode yang mengharapkan string nyata
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');

Ini berada dalam nada yang sama !!xsebagai lawan x===truedan menguji apakah ada sesuatu yang seperti array bukan memerlukan array yang sebenarnya.
objek jQuery; apakah mereka array? Tidak. Apakah mereka cukup baik? Ya, Anda dapat menjalankannya melalui Array.prototypefungsi dengan baik.
Fleksibilitas inilah yang memberi JS kekuatannya, dan pengujian untuk string secara spesifik membuat kode Anda kurang dapat dioperasikan.

Output di atas adalah:

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"

Jadi, ini semua tentang mengapa Anda ingin tahu apakah ada masalah.
Jika, seperti saya, Anda tiba di sini dari google dan ingin melihat apakah ada sesuatu yang mirip string , inilah jawabannya.
Itu bahkan tidak mahal kecuali jika Anda bekerja dengan array char sangat panjang atau sangat bersarang.
Ini karena itu semua jika pernyataan, tidak ada fungsi panggilan suka .toString().
Kecuali jika Anda mencoba untuk melihat apakah array char dengan objek yang hanya memiliki toString()karakter multi-byte, dalam hal ini tidak ada cara lain untuk memeriksa kecuali untuk membuat string, dan menghitung karakter byte, masing-masing.

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

Termasuk pilihan untuk

  • tanyakan metode mana yang dianggap sebagai string-y
  • kecualikan metode deteksi string (mis. jika Anda tidak suka .toString())

Berikut ini lebih banyak tes karena saya seorang penyelesaian:

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});
  • Semua kasus negatif tampaknya diperhitungkan
  • Ini harus dijalankan di browser> = IE8
  • Array array dengan beberapa byte yang didukung pada browser dengan dukungan string iterator

Keluaran:

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"
Hashbrown
sumber
1

Hanya untuk memperluas jawaban @ DRAX , saya akan melakukan ini:

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

Ini akan memperhitungkan juga untuk nulls dan undefinedtipe, dan itu akan menangani tipe non-string, seperti 0.

ahmd0
sumber
1

Ini cukup baik untukku.

PERINGATAN: Ini bukan solusi yang sempurna. Lihat bagian bawah posting saya.

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

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

Dan Anda bisa menggunakan ini seperti di bawah ini.

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

PERINGATAN: Ini berfungsi salah dalam hal:

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

isString(obj) //should be false, but true
Tomozma
sumber
-1

Anda dapat menggunakan fungsi ini untuk menentukan jenis apa pun:

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

Untuk memeriksa apakah suatu variabel adalah string:

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

Pato
sumber
-2

Saya tidak yakin apakah maksud Anda mengetahui apakah itu tipe stringterlepas dari isinya, atau apakah isinya angka atau string, terlepas dari jenisnya.

Jadi untuk mengetahui apakah tipenya adalah string, itu sudah dijawab.
Tetapi untuk mengetahui berdasarkan isinya jika berupa string atau angka, saya akan menggunakan ini:

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

Dan untuk beberapa contoh:

isNumber(123);   //true
isNumber('123'); //true
isNumber('123a');//false
isNumber('');    //false
Aryeh Beitz
sumber
Saya pikir saya awalnya bertanya bagaimana memeriksa jenis, meskipun saya tidak tahu bagaimana bahkan membentuk pertanyaan saat itu. (Dan saya mungkin hanya akan melakukan ini dengan /^\d+$/.test('123')untuk menghindari seluk-beluk masalah parsing potensial)
Olical