ตรวจสอบว่าตัวแปรเป็นสตริงใน JavaScript


1741

ฉันจะทราบได้อย่างไรว่าตัวแปรเป็นสตริงหรืออย่างอื่นใน JavaScript

คำตอบ:


1691

คุณสามารถใช้typeofโอเปอเรเตอร์:

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"

ตัวอย่างจากหน้าเว็บนี้ (ตัวอย่างได้รับการแก้ไขเล็กน้อย)

นี้จะไม่ทำงานตามที่คาดไว้ในกรณีของสตริงที่สร้างขึ้นด้วยnew String()แต่ตอนนี้ไม่ค่อยมีใครใช้และแนะนำกับ[1] [2] ดูคำตอบอื่น ๆ สำหรับวิธีจัดการกับสิ่งเหล่านี้หากคุณต้องการ


  1. คู่มือสไตล์ Google JavaScript กล่าวว่าจะไม่เคยใช้ห่อวัตถุดั้งเดิม
  2. ดักลาส Crockford แนะนำว่าห่อวัตถุดั้งเดิมจะเลิก

45
@ Wolfy87 โปรดทราบว่ามีบางกรณีที่ชนิดของ stringValue อาจส่งคืน "object" แทน "string" ดูความคิดเห็นเกี่ยวกับคำตอบของฉัน
DRAX

163
คำตอบที่ฉันต้องการ การโต้เถียงกับมันคือ 'ล้มเหลว' สำหรับสตริงที่มีการห่อวัตถุnew String('foo')แต่นั่นไม่สำคัญเพราะสตริงที่ถูกห่อด้วยวัตถุนั้นเป็นคุณสมบัติที่ไร้ค่าที่คุณไม่ควรใช้ คู่มือสไตล์ Google ห้ามมิให้พวกเขาดักลาสคร๊อคฟอร์ดต้องการเลิกใช้และไม่มีห้องสมุดที่ใช้ แกล้งทำเป็นว่าพวกเขาไม่มีตัวตนและใช้typeofโดยไม่กลัว
Mark Amery


2
@DanielLe เพราะเขาเสนอการแทนที่ซึ่งแก้ไขปัญหาบางอย่างไม่ใช่เพราะเขาขัดต่อหลักการ
Vsevolod Golovanov

4
ถ้ามันทำให้คุณปวดหัว 99.99% ของเวลานั้นเป็นเพราะคุณไม่ได้จัดโครงสร้างรหัสของคุณอย่างถูกต้อง นั่นไม่ใช่ความผิดของ NaN สำหรับสิ่งที่มีอยู่และทำในสิ่งที่คุณควรจดบันทึกเรียนรู้จากและจำไว้ในครั้งต่อไปที่คุณทำงานกับรหัสที่อาจให้ผล
Kamermans ของไมค์ 'Pomax'

1907

นี่คือสิ่งที่ได้ผลสำหรับฉัน:

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

77
"myVar instanceof String" ทำอะไรเกินกว่านี้หรือไม่ "typeof myVar == 'string'"
svth

81
@svth ฉันจำได้ ใน JavaScript คุณสามารถมีประเภทของตัวแปรของสตริงหรือประเภทของวัตถุซึ่งเป็นคลาสของ String (สิ่งเดียวกัน - ทั้งสองเป็นสตริง - แต่กำหนดไว้แตกต่างกัน) นั่นคือเหตุผลที่มีการตรวจสอบสองครั้ง
DRAX

38
var somevar = string ใหม่ ('somestring') console.log (type of somevar) // object
Danubian Sailor

82
-1 เนื่องจากการinstanceofตรวจสอบที่นี่เป็นเสียงที่ไม่มีจุดหมายเว้นแต่คุณจะปฏิบัติตามแนวทางการเขียนโค้ดที่ผิดปกติมากและคำตอบนี้ไม่ได้อธิบายสิ่งที่ทำหรือสาเหตุที่คุณอาจใช้งาน เหตุผลเดียวที่คุณต้องการคือถ้าคุณใช้สตริงที่พันด้วยวัตถุ แต่สตริงที่ล้อมรอบด้วยวัตถุนั้นเป็นคุณสมบัติที่ไร้ค่าซึ่งไม่มีใครใช้และ Google และ Crockford ต่างก็ประณามการปฏิบัติที่ไม่ดี ( google-styleguide.googlecode.com/svn/) trunk / … , crockford.com/javascript/recommend.html )
Mark Amery

79
ฉันไม่เห็นด้วยอย่างแรงว่าการเขียนรหัสที่เป็นของแข็งซึ่งจัดการกับกรณีที่ไม่ถูกต้องเป็นสิ่งที่ควรหลีกเลี่ยง ตรวจสอบทั้งสองอย่างtypeofและinstanceofรู้สึกว่าเป็นคำแนะนำที่ดีถ้าผู้อื่นอาจเรียกรหัสของคุณ @ postmessageกรณีขอบของ MarkAmery มีความสำคัญหากคุณถามว่า "ฉันแค่เป็นpostmessageอะไร?" - แต่คุณคาดหวังว่าจะได้รับการจัดการที่อินเทอร์เฟซและไม่ได้รับอนุญาตให้เผยแพร่ ที่อื่นดูเหมือนว่าถูกต้องในการจัดการกับวิธีการเข้ารหัสที่ไม่คัดค้านถึงแม้ว่าความสวยงามของ JS บางคนไม่เห็นด้วยกับพวกเขา อย่าคอมเม้นต์โค้ดของคุณว่าเป็นการยอมรับ String เว้นแต่ว่ามันจะเป็นจริง!
Dewi Morgan

157

ตั้งแต่ผู้คนมากกว่า 580 คนโหวตให้กับคำตอบที่ไม่ถูกต้องและ 800+ โหวตให้กับการทำงาน แต่คำตอบแบบปืนลูกซองฉันคิดว่ามันน่าจะคุ้มค่าที่จะทำซ้ำคำตอบของฉันในรูปแบบที่เรียบง่ายกว่าที่ทุกคนสามารถเข้าใจได้

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

หรือแบบอินไลน์ (ฉันมีการตั้งค่า UltiSnip สำหรับสิ่งนี้):

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

FYI, คำตอบของ Pablo Santa Cruz นั้นผิดเพราะtypeof new String("string")เป็นobject

คำตอบของ DRAX นั้นถูกต้องและใช้งานได้และควรเป็นคำตอบที่ถูกต้อง (เนื่องจาก Pablo Santa Cruz นั้นไม่ถูกต้องแน่นอนที่สุดและฉันจะไม่คัดค้านการลงคะแนนความนิยม)

อย่างไรก็ตามคำตอบนี้ถูกต้องแน่นอนและจริง ๆ แล้วเป็นคำตอบที่ดีที่สุด (ยกเว้นบางทีสำหรับคำแนะนำในการใช้lodash / ขีดล่าง ) การปฏิเสธความรับผิดชอบ: ฉันมีส่วนร่วมในฐานรหัส Lodash 4

คำตอบเดิมของฉัน (ซึ่งเห็นได้ชัดว่าบินผ่านหัวจำนวนมาก) ดังนี้:

ฉันแปลงรหัสนี้จาก underscore.js:

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

ที่จะกำหนด isString, isNumber, ฯลฯ


ใน Node.js สิ่งนี้สามารถนำมาใช้เป็นโมดูล:

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

[แก้ไข]: Object.prototype.toString.call(x)ทำงานเพื่อวิเคราะห์ระหว่างฟังก์ชั่นและฟังก์ชั่น async เช่นกัน:

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 (ด้วยเหตุผลอะไรแปลก ๆ ) แต่คุณไม่ได้ใช้ที่นี่ ยิ่งกว่านั้นคุณทำให้เนมสเปซส่วนกลางมีฟังก์ชัน ใน node.js คุณต้องสร้างโมดูลที่มีฟังก์ชั่นเหล่านี้ทั้งหมด (คุณสามารถใช้global || windowแทนwindowแต่นั่นจะเป็นวิธีที่ไม่ดีในการแก้ปัญหาที่คุณไม่ควรมีในตอนแรก)
Benjamin Gruenbaum

19
@BenjaminGruenbaum ฉันมาหาคำตอบของคำถาม OP และไม่ชอบคำตอบใด ๆ ดังนั้นฉันจึงตรวจสอบสิ่งที่ขีดเส้นใต้ทำและคิดว่ามันดีพอที่จะแยกและแก้ไขเล็กน้อย (เพื่อหลีกเลี่ยงการโหลดไลเดอร์ไลบรารี) ฉันจะชี้แจงโพสต์ของฉัน
Orwellophile

2
@Orwellophile เจ๋งฉันเข้าใจแล้วคำตอบเดิมของคุณเป็นประโยคที่เหมือนว่าคุณกำลังขีดเส้นใต้ตัวเอง โดยส่วนตัวฉันแค่ตรวจสอบmyObject+"" === myObjectเพื่อตรวจสอบว่าวัตถุเป็นสตริง (หรือดีกว่าฉันจะไม่พิมพ์ตรวจสอบในระบบประเภทพฤติกรรมขับเคลื่อนในตอนแรก)
Benjamin Gruenbaum

18
@Orwellophile ดีกว่าคำตอบของ DRAX อย่างไร
Pacerier

3
JS สนับสนุนลิง patching ดังนั้นจึงเป็นไปได้ที่จะ re-กำหนดในtoString Object.prototypeดังนั้นฉันขอยืนยันว่าการพึ่งพาtoStringการตรวจสอบประเภทของวัตถุคือวิธีปฏิบัติที่ไม่ดี
Andre Rodrigues

84

ผมขอแนะนำให้ใช้ฟังก์ชั่นจากjQueryหรือlodash / เน้น ใช้ง่ายกว่าและอ่านง่ายกว่า

ฟังก์ชั่นใดจะจัดการกรณี DRAX ที่กล่าวถึง ... นั่นคือพวกเขาทั้งสองตรวจสอบว่า (A) ตัวแปรเป็นสตริงตัวอักษรหรือ (B) มันเป็นตัวอย่างของวัตถุสตริง ในทั้งสองกรณีฟังก์ชั่นเหล่านี้จะระบุค่าอย่างถูกต้องว่าเป็นสตริง

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

ดูเอกสารคู่มือ lodash สำหรับ _.isString ()สำหรับรายละเอียดเพิ่มเติม

ดูjQuery Documentation สำหรับ $ .type ()สำหรับรายละเอียดเพิ่มเติม


96
นี่เป็นสิ่งสำคัญในสิ่งที่ผิดปกติกับชุมชน JS - การตรวจสอบกับชนิดดั้งเดิมเป็นหนึ่งซับและเกี่ยวข้องกับการสร้างภาษา (หนึ่งในพื้นฐาน) แต่คุณแนะนำให้ใช้ไลบรารีภายนอก หากมีคนใช้ห้องสมุดเหล่านี้อยู่แล้วอาจเป็นความคิดที่ดี แต่การดาวน์โหลดเพื่อใช้แทนการตรวจสอบประเภทนั้นเป็นเรื่องที่เกินเลยไป
Rafał Wrzeszcz

5
ฉันจะเห็นด้วยกับ Rafal ฉันเห็นทุกที่เพื่อปรับปรุง "ความสามารถในการอ่าน" ให้ใช้ไลบรารีภายนอกเหล่านี้ หากคุณรู้จัก JavaScript นั่นหมายความว่าอ่านได้ง่ายกว่าบางไลบรารีภายนอกที่คุณไม่ได้ใช้ _.every()ในตอนแรกมันสับสนเล็กน้อยในการใช้งานและบางสิ่งที่เรียบง่ายอย่างที่_.isBoolean()devs บริษัท ของฉันสับสน นักพัฒนาคิดว่าผิดพลาดว่ามันจะผิดถ้าค่านั้นเป็นบูลีนและเป็นเท็จ อ่านภาษาอังกฤษได้ง่ายกว่าภาษาเยอรมันสำหรับฉันเพราะฉันไม่รู้ภาษาเยอรมัน เรียนรู้ JavaScript และทุกอย่างจะสมเหตุสมผล
John Harding

20
@ RafałWrzeszczห้องสมุดเหล่านี้ค่อนข้างใช้กันอย่างแพร่หลายและมีฟังก์ชั่นที่เป็นประโยชน์ (และทดสอบ) โดยเฉพาะที่พักอาศัย ฉันจะไม่แนะนำให้ใครบางคนดาวน์โหลดไลบรารีเท่านั้นที่จะใช้สำหรับโซลูชันนี้ .... แต่ฉันจะแนะนำให้นักพัฒนา javascript ทุกคนดาวน์โหลดไลบรารีนี้และดูว่าพวกเขาพลาดอะไรบ้าง ;)
ClearCloud8

13
ทุกคนพลาดจุดห้องสมุดเหมือน Lodash: ไม่ใช่ความเร็ว ไม่ใช่ "ความง่ายในการพัฒนา" เหตุผลที่ใช้ไลบรารีเช่น Lodash ให้ "การป้องกัน" กับปัญหาที่จะทำให้แอป js ของคุณระเบิด ข้อผิดพลาดร้ายแรงเกิดขึ้นเมื่อคุณพยายามดำเนินการกับสตริงในวัตถุ (หรือในทางกลับกัน) และ Lodash ให้คุณค่าอย่างมากในการป้องกันข้อผิดพลาดเหล่านั้น
random_user_name

1
โปรดจำไว้ว่าหลายคนจะทำสิ่งนี้ในสภาพแวดล้อมที่เหมือน Node หรือ Node และมีเพียงไม่กี่คนที่จะใช้ jQuery
Matt Fletcher

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

ฉันเห็นสิ่งนั้นที่นี่:

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


4
ฉันคิดว่าโซลูชันนี้มีประสิทธิภาพสูงสุดเนื่องจากสามารถจัดการกับสถานการณ์อ้างอิงข้ามเฟรม / ข้ามหน้าต่างตามที่ระบุไว้ใน URL ที่ให้ไว้ในคำตอบ
ewh

1
คำตอบที่ดีดูเหมือน Underscore.js ก็ใช้วิธีนี้เช่นกัน!
ดาน

1
@ling แค่อยากรู้อยากเห็นทำไมคุณใส่วงเล็บไว้Object.prototype.toString.call(obj) === '[object String]'?
StubbornShowaGuy

@Earlee คุณหมายถึง(x === y)มีการอ่านที่ดีกว่าx === y?
StubbornShowaGuy

@StubbornShowaGuy ในความคิดของฉันใช่ นอกจากนี้ยังเกี่ยวกับความมั่นคง ฉันมักจะใช้วงเล็บเมื่อคืนค่า
Aquarelle

28

วิธีที่ดีที่สุด:

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

แต่ละสิ่งเหล่านี้ถูกสร้างขึ้นโดยฟังก์ชันคลาสที่เหมาะสมเช่น "new Object ()" เป็นต้น

ยิ่งไปกว่านั้น Duck-Typing: "ถ้ามันดูเหมือนเป็ดเดินเหมือนเป็ดและมีกลิ่นเหมือนเป็ด - มันต้องเป็นอาร์เรย์" ความหมายตรวจสอบคุณสมบัติของมัน

หวังว่านี่จะช่วยได้

แก้ไข; 2016/12/05

โปรดจำไว้ว่าคุณสามารถใช้วิธีการต่างๆรวมกันได้ นี่คือตัวอย่างการใช้แผนที่แบบอินไลน์ของการกระทำกับtypeof :

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

นี่คือตัวอย่าง 'โลกแห่งความจริง' เพิ่มเติมของการใช้อินไลน์แผนที่:

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

ฟังก์ชั่นนี้จะใช้ [กำหนดเอง] "type-casting" - ค่อนข้าง "type - / - value-mapping" - เพื่อคิดออกว่าตัวแปร "มีอยู่จริง" ตอนนี้คุณสามารถแยกผมที่น่ารังเกียจระหว่างnull & 0!

หลายครั้งที่คุณไม่ใส่ใจเกี่ยวกับประเภทของมันคุณไม่สนใจเกี่ยวกับประเภทของอีกวิธีในการหลีกเลี่ยงการพิมพ์คือการรวมชุด 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) ...;
}

ทั้งสองNumber.prototype และ มีString.prototype .toString() methodคุณตรวจสอบให้แน่ใจว่าสตริงที่เทียบเท่าของตัวเลขนั้นเท่ากันและจากนั้นคุณต้องแน่ใจว่าคุณส่งมันเข้าไปในhttpฟังก์ชันเป็นNumberฟังก์ชั่นเป็นกล่าวอีกนัยหนึ่งเราไม่ได้สนใจว่ามันเป็นประเภทอะไร

หวังว่าจะช่วยให้คุณทำงานกับ :)


คุณจะต้องตรวจสอบหมายเลขเก่าธรรมดาอื่น ๆ เนื่องจากการพยายามที่จะใช้ทรัพย์สินคอนสตรัคของพวกเขาจะล้มเหลว:

@torazaburo ทำงานได้ดีสำหรับฉันตอนนี้ในคอนโซล Chrome อะไรทำให้คุณคิดว่ามันไม่ทำงาน
Mark Amery

2
@torazaburo คุณอาจต้องการเล่นกับยืนยัน ( (o.constructor === Number || s.constructor === Boolean)) Anecdotally parseIntและNaNเป็นเครื่องมือที่เปราะบาง แต่ทรงพลัง เพียงจำไว้ว่า Not-a-Number ไม่ใช่ Not-a-Number และสามารถกำหนดไม่ได้
Cody

1
a.constructor === Array ผิดและสามารถล้มเหลวบางครั้งใช้ Array.isArray ดูweb.mit.edu/jwalden/www/isArray.html
axkibe

1
ตกลงนี้ไม่ปลอดภัย วิธีที่ดีกว่าคือใช้การตรวจสอบคุณสมบัติ - นั่นเป็นวิธีเดียวที่ไม่ปลอดภัยอย่างแท้จริงในขณะนี้ ตัวอย่าง: หรือif(thing.call) { 'its a function'; } if(thing.defineProperties) { 'its an object'; }ขอบคุณสำหรับการป้อนข้อมูล axkibe!
โคดี

17

ฉันไม่สามารถเห็นได้อย่างจริงใจว่าทำไมไม่มีใครใช้typeofในกรณีนี้:

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

ใช่มันจะล้มเหลวจากสายอักขระที่ห่อด้วยวัตถุ (เช่นnew String('foo')) แต่สิ่งเหล่านี้ได้รับการยอมรับอย่างกว้างขวางว่าเป็นแนวปฏิบัติที่ไม่ดีและเครื่องมือการพัฒนาที่ทันสมัยส่วนใหญ่มีแนวโน้มที่จะกีดกันการใช้งานของพวกเขา (ถ้าคุณเห็นมันเพียงแก้ไขมัน!)

Object.prototype.toStringเคล็ดลับคือสิ่งที่นักพัฒนา front-end ทั้งหมดได้รับการพบความผิดของการทำวันหนึ่งในอาชีพของพวกเขา แต่อย่าให้มันหลอกคุณโดยเงาของฉลาด: มันจะทำลายเร็วที่สุดเท่าที่บางสิ่งบางอย่างลิงแพทช์ต้นแบบวัตถุ:

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

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

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

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


15

ฉันชอบที่จะใช้วิธีแก้ปัญหาง่ายๆนี้:

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

3
มันแตกต่างจากคำตอบของโคดี้ 4 ปีต่อมาอย่างไร?
Jonathan H

3
คำตอบของ @Sheljohn Cody นั้นยอดเยี่ยม คำตอบของฉัน (ข้อความสมบูรณ์) สั้นกว่าและตรงประเด็น คุณถาม ... :)
ScottyG

ในฐานะที่เป็นฟังก์ชั่นนี้จะต้องมีวิธีการจัดการกับundefinedและnullและยังคงได้รับคำตอบที่ถูกต้องสำหรับสตริงว่าง (ทั้ง''และnew String(''))
MikeBeaton

@MikeBeaton (mystring || false) && mystring.constructor === Stringไม่มีปัญหา: ฉันใช้ false ในกรณีที่ใช้ในฟังก์ชันที่ต้องส่งคืนบูลีน
อนิจจา

13

นี่เป็นตัวอย่างที่ดีว่าทำไมประสิทธิภาพจึงสำคัญ:

การทำอะไรที่ง่ายเหมือนการทดสอบสตริงอาจมีราคาแพงถ้าทำไม่ถูกต้อง

ตัวอย่างเช่นถ้าฉันต้องการเขียนฟังก์ชั่นเพื่อทดสอบว่าบางอย่างเป็นสตริงฉันสามารถทำได้ด้วยวิธีใดวิธีหนึ่งจากสองวิธี:

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

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

ทั้งสองอย่างนี้ตรงไปตรงมาดังนั้นสิ่งที่อาจส่งผลกระทบต่อประสิทธิภาพ? โดยทั่วไปการเรียกใช้ฟังก์ชันอาจมีราคาแพงโดยเฉพาะถ้าคุณไม่รู้ว่าเกิดอะไรขึ้นภายใน ในตัวอย่างแรกมีการเรียกใช้ฟังก์ชันไปยังเมธอด toString ของ Object ในตัวอย่างที่สองไม่มีการเรียกใช้ฟังก์ชันเนื่องจาก typeof และ instanceof เป็นตัวดำเนินการ ตัวดำเนินการเร็วกว่าการเรียกใช้ฟังก์ชันอย่างมาก

เมื่อทดสอบประสิทธิภาพแล้วตัวอย่างที่ 1 คือ 79% ช้ากว่าตัวอย่างที่ 2!

ดูการทดสอบ: https://jsperf.com/isstringtype


ลิงก์ทดสอบใช้งานไม่ได้ แต่ฉันเชื่อว่าคุณ ข้อมูลประเภทนี้สำคัญมาก IMHO สิ่งนี้ควรเป็นถ้าไม่ใช่คำตอบที่ upvoted ที่สุดอย่างน้อยความคิดเห็นที่ upvoted ที่สุดในคำตอบที่เป็นปัจจุบัน
Coderer

typeof str === 'string' || str instanceof String(สามารถวางวงเล็บซึ่งฉันชอบในif (..)บางกรณี); ไม่ว่าการตรวจสอบทั้งชนิดดั้งเดิมและชนิดของวัตถุใน # 2 นั้นชัดเจนและเพียงพอ เช็คเหล่านี้ควรจะ 'หายาก' อยู่ดี
2864740

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

ใช้งานได้ทั้งตัวอักษรสตริงlet s = 'blah'และ Object Stringslet s = new String('blah')


3
ความสนใจ! สิ่งนี้จะล้มเหลวในสตริงว่างเนื่องจากสิ่งเหล่านี้เป็นเท็จ
Philipp Sumi

8

นำมาจาก 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

หากใครต้องการรู้แหล่งที่มาก็คือgithub.com/lodash/lodash/blob/master/isString.js
Ricardo Canelas

5

ฉันคิดว่าโซลูชัน @customcommander ควรเพียงพอใน 90% ของกรณีของคุณ:

typeof str === 'string'

ควรให้บริการคุณอย่างถูกต้อง (โดยปกติเนื่องจากไม่มีเหตุผลที่จะมี new String('something')ในรหัสของคุณ)

หากคุณสนใจที่จะจัดการ Stringวัตถุเช่นกัน (เช่นคุณคาดหวังว่าจะมี var จากบุคคลที่สาม) จากนั้นใช้ lodash ตามที่ @ ClearCloud8 แนะนำดูเหมือนว่าเป็นโซลูชันที่ชัดเจนเรียบง่ายและสง่างาม

อย่างไรก็ตามฉันขอแนะนำให้ใช้ความระมัดระวังกับห้องสมุดเช่น lodash เนื่องจากขนาดของห้องสมุด แทนที่จะทำ

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

ซึ่งนำวัตถุ lodash ขนาดใหญ่มาทั้งหมดฉันขอแนะนำบางอย่างเช่น:

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

และด้วยการรวมกลุ่มที่เรียบง่ายคุณควรจะใช้ได้ (ฉันอ้างถึงที่นี่เพื่อรหัสลูกค้า)


ทำไม === เมื่อ == เพียงพอ
zavr

4

หากคุณทำงานกับสภาวะแวดล้อม node.js คุณสามารถใช้ฟังก์ชัน built-in isString ใน utils

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

แก้ไข: ดังที่ @Jehy กล่าวถึงสิ่งนี้เลิกใช้แล้วตั้งแต่ v4


มีผู้ใดทดแทนหรือไม่
Anthony Kong

3
เอกสารพูดว่า "ใช้typeof value === 'string'แทน"
Mr Rogers

x = new String('x'); x.isString(x);ผลตอบแทนที่เป็นเท็จ มีutil.types.isStringObject()แต่ที่ส่งกลับเท็จสำหรับx = 'x'สตริงประเภท สองฟังก์ชั่นยูทิลิตี้ที่ไม่ได้ให้ยูทิลิตี้อย่างแน่นอน ...
spinkus

4

วิธีการต่อไปนี้จะตรวจสอบว่าตัวแปรใด ๆ เป็นสตริง ( รวมถึงตัวแปรที่ไม่มีอยู่ )

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

ฉันก็พบว่ามันใช้งานได้ดีเช่นกันและมันสั้นกว่าตัวอย่างอื่นมาก

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

โดยเชื่อมต่อกับคำพูดที่ว่างเปล่ามันจะเปลี่ยนค่าเป็นสตริง หากmyVarเป็นสตริงอยู่แล้วข้อความสั่ง if จะสำเร็จ


3
ปัญหาเดียวที่คุณกำลังบีบบังคับตัวแปรคือเมื่อคุณต้องการตรวจสอบประเภทของมัน มันดูค่อนข้างแพงเมื่อเทียบกับtypeofฉัน
Olical

1
ใช่แล้วคุณพูดถูก jsperfบอกว่ามันเป็นประมาณ 20% ช้ากว่าแต่ยังคงค่อนข้างเร็วกว่าtypeof toStringทั้งสองวิธีฉันเดาว่าฉันชอบไวยากรณ์สำหรับการข่มขู่
Chris Dolphin

4
สิ่งนี้ใช้ไม่ได้กับชนิดของสตริง var s = new String('abc'); > s === s + '' > false
user5672998

1
ไม่ได้ทำงานกับยูเอสที่สร้างประเภทของnew String w3schools.com/js/tryit.asp?filename=tryjs_string_object2object
Chris Dolphin

เป็นความคิดที่ดี แต่หลุดออกจากขอบกล่องของวัตถุที่พันกัน
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 === สตริงจะกลับเท็จเป็นโมฆะหรือไม่ได้กำหนด?
Jules Manson

1
@JulesManson: falseมันจะโยนความผิดพลาดที่ไม่ได้ผลิต
Ry-

3

ฉันพบเทคนิคง่าย ๆ นี้มีประโยชน์ในการพิมพ์ตรวจสอบสำหรับ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

เทคนิคเดียวกันนี้ใช้กับ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

และสำหรับ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

เหมือนกันสำหรับวัตถุ -

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

NB, regexps, อาร์เรย์และฟังก์ชั่นถือเป็นวัตถุเช่นกัน

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)    

แต่การตรวจสอบArrayนั้นแตกต่างกันเล็กน้อย -

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

เทคนิคนี้ใช้ไม่ได้กับฟังก์ชั่นอย่างไรก็ตาม -

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

var x = new String(x); String(x)===xผลตอบแทนที่เป็นเท็จ อย่างไรก็ตาม({}).toString.call(x).search(/String/)>0จะส่งคืนสำหรับสิ่งที่เป็นสตริงเสมอ
unsynchronized

1
function isClass(x,re){return ({}).toString.call(x).search(re)>0;}; isClass("hello",/String/) หรือisClass(3,/Number/)หรือisClass(null,/Null/)
ไนซ์

2

ทางออกที่ง่ายจะเป็น:

var x = "hello"

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

1
สิ่งนี้จะไม่ตรวจสอบว่าเป็นสตริงหรือไม่ มันทำให้เป็นสตริงสิ่งต่าง ๆ มากมายมีtoString()ฟังก์ชั่น
Muhammad Umer

7
@MuhammadUmer ใช่มันจะแปลงมันเป็นสตริง แต่จากนั้นตรวจสอบตัวตนกับค่าเดิมซึ่งจะเป็นจริงถ้าค่าเดิมยังเป็นสตริง
MrWhite

4
นี่เป็นสิ่งที่ผิด: คุณไม่สามารถโทรหา.toStringค่าใด ๆ ลองถ้า x ที่จะตรวจสอบเป็นโมฆะหรือไม่ได้กำหนดรหัสของคุณโยนข้อยกเว้น
user5672998

1
แนวคิดนี้ยังคงใช้งานได้ x === สตริง (x) ปลอดภัยและใช้งานได้
MártonSári

จริงๆ? วิธีนี้ดูเหมือนแปลกเกินไปสำหรับฉันเพราะtoString()วิธีการอาจถูกเขียนทับและอาจทำให้เกิดข้อยกเว้น (เนื่องจากมีการใช้งานบางอย่าง) และเช็คของคุณจะไม่ทำงานอย่างแน่นอน แนวคิดหลักคือคุณไม่ควรเรียกวิธีการที่ไม่เกี่ยวข้องกับสิ่งที่คุณต้องการรับ ฉันไม่ได้พูดถึงค่าใช้จ่ายที่ไม่จำเป็นที่เกี่ยวข้องกับtoStringวิธีการ downvoting
Rustem Zinnatullin

2

ผู้ช่วย Typechecker:

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

การใช้งาน:

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

นอกจากนี้หากคุณต้องการให้เกิดซ้ำ (เช่น Array ที่เป็นวัตถุ) คุณสามารถใช้ instanceofคุณสามารถใช้

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


2

ฉันจะไปเส้นทางที่แตกต่างไปยังส่วนที่เหลือที่นี่ซึ่งพยายามที่จะบอกว่าตัวแปรเป็นเฉพาะหรือเป็นสมาชิกของประเภทชุดที่เฉพาะเจาะจง
JS ถูกสร้างจากการพิมพ์เป็ด หากสิ่งที่ quacks เช่นสตริงเราสามารถและควรใช้มันเช่นสตริง

คือ7สตริง? แล้วทำไมไม่/\d/.test(7)ทำงานหรือไม่
คือ{toString:()=>('hello there')}สตริง? แล้วทำไมไม่({toString:()=>('hello there')}) + '\ngeneral kenobi!'ทำงานหรือไม่
นี่ไม่ใช่คำถามที่ควรทำทำงานข้างต้นจุดที่พวกเขาทำ

ดังนั้นฉันจึงสร้างduckyString()ฟังก์ชั่น
ด้านล่างฉันทดสอบหลายกรณีที่ไม่ได้รับคำตอบจากคำตอบอื่น ๆ สำหรับแต่ละรหัส:

  • ตั้งค่าตัวแปรสตริงเหมือน
  • รันการทำงานของสตริงที่เหมือนกันกับมันและสตริงจริงเพื่อเปรียบเทียบผลลัพธ์ (พิสูจน์ได้ว่าพวกเขาสามารถได้รับการปฏิบัติเหมือนสตริง)
  • แปลงสตริงเหมือนสตริงจริงเพื่อแสดงให้คุณduckyString()ป้อนค่าอินพุตปกติสำหรับโค้ดที่ต้องการสตริงจริง
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');

สิ่งนี้อยู่ในหลอดเลือดดำเดียว!!xกับเมื่อเทียบกับx===trueและทดสอบว่ามีสิ่งใดที่เหมือนอาร์เรย์แทนที่จะต้องใช้อาร์เรย์จริง
วัตถุ jQuery; พวกเขากำลังอาร์เรย์? ไม่ดีพอหรือไม่ ใช่คุณสามารถเรียกใช้พวกเขาผ่านArray.prototypeฟังก์ชั่นได้ดี
มันเป็นความยืดหยุ่นที่ให้อำนาจของตน JS และการทดสอบสำหรับสตริงเฉพาะทำให้รหัสของคุณทำงานร่วมกันน้อย

ผลลัพธ์ของข้างต้นคือ:

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"

ดังนั้นจึงเป็นเรื่องเกี่ยวกับสาเหตุที่คุณต้องการทราบว่ามีบางอย่างของสตริงหรือไม่
ถ้าอย่างฉันคุณมาถึงที่นี่จาก google และต้องการดูว่ามีอะไรที่เหมือนสตริงหรือเปล่านี่คือคำตอบ
มันไม่ได้มีราคาแพงจนกว่าคุณจะได้ทำงานกับอาร์เรย์ถ่านที่ยาวหรือลึกจนเกินไป เพราะมันเป็นสิ่งที่ถ้างบไม่มีฟังก์ชั่นการโทรเช่น
ยกเว้นถ้าคุณกำลังพยายามดูว่าอาร์เรย์อักขระที่มีวัตถุที่มีอักขระของหรือหลายไบต์เท่านั้นในกรณีนี้ไม่มีวิธีอื่นในการตรวจสอบยกเว้นเพื่อสร้างสตริงและนับอักขระที่ประกอบกันเป็นไบต์ตามลำดับ.toString()
toString()

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

รวมเป็นตัวเลือก

  • ถามว่าวิธีไหนถือว่าเป็น string-y
  • วิธีการแยกการตรวจจับสตริง (เช่นถ้าคุณไม่ชอบ.toString())

นี่คือการทดสอบเพิ่มเติมเพราะฉันเป็นผู้ดำเนินการเสร็จสิ้น:

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});
  • กรณีลบทั้งหมดดูเหมือนจะถูกนำมาพิจารณา
  • สิ่งนี้ควรทำงานบนเบราว์เซอร์> = IE8
  • อักขระอาร์เรย์ที่สนับสนุนหลายไบต์บนเบราว์เซอร์ที่มีการสนับสนุนตัววนซ้ำสตริง

เอาท์พุท:

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 ฉันจะทำสิ่งนี้:

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

มันจะคิดยังnullและประเภทและมันจะดูแลประเภทที่ไม่ใช่สตริงเช่นundefined0


1

มันดีพอสำหรับฉัน

คำเตือน:นี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบ ดูที่ด้านล่างของโพสต์ของฉัน

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

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

และคุณสามารถใช้สิ่งนี้เช่นด้านล่าง

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

คำเตือน:สิ่งนี้ทำงานไม่ถูกต้องในกรณี:

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

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

-1

คุณสามารถใช้ฟังก์ชั่นนี้เพื่อกำหนดประเภทของอะไร:

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

วิธีตรวจสอบว่าตัวแปรเป็นสตริงหรือไม่:

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โดยไม่คำนึงถึงเนื้อหาของมันหรือว่าเนื้อหานั้นเป็นตัวเลขหรือสตริงไม่ว่าจะเป็นประเภทใด

ดังนั้นเพื่อทราบว่าประเภทของมันคือสตริงหรือไม่นั้นได้รับการตอบแล้ว
แต่รู้ตามเนื้อหาถ้าเป็นสตริงหรือตัวเลขฉันจะใช้นี้

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

และสำหรับบางตัวอย่าง:

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

ฉันคิดว่าฉันเดิมถามวิธีการตรวจสอบประเภทแม้ว่าฉันไม่ทราบวิธีการตั้งคำถามได้ (และฉันอาจจะทำเช่นนี้กับ/^\d+$/.test('123')เพื่อหลีกเลี่ยงความซับซ้อนของปัญหาการแยกวิเคราะห์ที่อาจเกิดขึ้น)
Olical
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.