ฉันจะทราบได้อย่างไรว่าตัวแปรเป็นสตริงหรืออย่างอื่นใน JavaScript
ฉันจะทราบได้อย่างไรว่าตัวแปรเป็นสตริงหรืออย่างอื่นใน JavaScript
คำตอบ:
คุณสามารถใช้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] ดูคำตอบอื่น ๆ สำหรับวิธีจัดการกับสิ่งเหล่านี้หากคุณต้องการ
new String('foo')
แต่นั่นไม่สำคัญเพราะสตริงที่ถูกห่อด้วยวัตถุนั้นเป็นคุณสมบัติที่ไร้ค่าที่คุณไม่ควรใช้ คู่มือสไตล์ Google ห้ามมิให้พวกเขาดักลาสคร๊อคฟอร์ดต้องการเลิกใช้และไม่มีห้องสมุดที่ใช้ แกล้งทำเป็นว่าพวกเขาไม่มีตัวตนและใช้typeof
โดยไม่กลัว
นี่คือสิ่งที่ได้ผลสำหรับฉัน:
if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
instanceof
ตรวจสอบที่นี่เป็นเสียงที่ไม่มีจุดหมายเว้นแต่คุณจะปฏิบัติตามแนวทางการเขียนโค้ดที่ผิดปกติมากและคำตอบนี้ไม่ได้อธิบายสิ่งที่ทำหรือสาเหตุที่คุณอาจใช้งาน เหตุผลเดียวที่คุณต้องการคือถ้าคุณใช้สตริงที่พันด้วยวัตถุ แต่สตริงที่ล้อมรอบด้วยวัตถุนั้นเป็นคุณสมบัติที่ไร้ค่าซึ่งไม่มีใครใช้และ Google และ Crockford ต่างก็ประณามการปฏิบัติที่ไม่ดี ( google-styleguide.googlecode.com/svn/) trunk / … , crockford.com/javascript/recommend.html )
typeof
และinstanceof
รู้สึกว่าเป็นคำแนะนำที่ดีถ้าผู้อื่นอาจเรียกรหัสของคุณ @ postmessage
กรณีขอบของ MarkAmery มีความสำคัญหากคุณถามว่า "ฉันแค่เป็นpostmessage
อะไร?" - แต่คุณคาดหวังว่าจะได้รับการจัดการที่อินเทอร์เฟซและไม่ได้รับอนุญาตให้เผยแพร่ ที่อื่นดูเหมือนว่าถูกต้องในการจัดการกับวิธีการเข้ารหัสที่ไม่คัดค้านถึงแม้ว่าความสวยงามของ JS บางคนไม่เห็นด้วยกับพวกเขา อย่าคอมเม้นต์โค้ดของคุณว่าเป็นการยอมรับ String เว้นแต่ว่ามันจะเป็นจริง!
ตั้งแต่ผู้คนมากกว่า 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))
global || window
แทนwindow
แต่นั่นจะเป็นวิธีที่ไม่ดีในการแก้ปัญหาที่คุณไม่ควรมีในตอนแรก)
myObject+"" === myObject
เพื่อตรวจสอบว่าวัตถุเป็นสตริง (หรือดีกว่าฉันจะไม่พิมพ์ตรวจสอบในระบบประเภทพฤติกรรมขับเคลื่อนในตอนแรก)
toString
Object.prototype
ดังนั้นฉันขอยืนยันว่าการพึ่งพาtoString
การตรวจสอบประเภทของวัตถุคือวิธีปฏิบัติที่ไม่ดี
ผมขอแนะนำให้ใช้ฟังก์ชั่นจาก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 ()สำหรับรายละเอียดเพิ่มเติม
_.every()
ในตอนแรกมันสับสนเล็กน้อยในการใช้งานและบางสิ่งที่เรียบง่ายอย่างที่_.isBoolean()
devs บริษัท ของฉันสับสน นักพัฒนาคิดว่าผิดพลาดว่ามันจะผิดถ้าค่านั้นเป็นบูลีนและเป็นเท็จ อ่านภาษาอังกฤษได้ง่ายกว่าภาษาเยอรมันสำหรับฉันเพราะฉันไม่รู้ภาษาเยอรมัน เรียนรู้ JavaScript และทุกอย่างจะสมเหตุสมผล
function isString (obj) {
return (Object.prototype.toString.call(obj) === '[object String]');
}
ฉันเห็นสิ่งนั้นที่นี่:
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
Object.prototype.toString.call(obj) === '[object String]'
?
(x === y)
มีการอ่านที่ดีกว่าx === y
?
วิธีที่ดีที่สุด:
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: "ถ้ามันดูเหมือนเป็ดเดินเหมือนเป็ดและมีกลิ่นเหมือนเป็ด - มันต้องเป็นอาร์เรย์" ความหมายตรวจสอบคุณสมบัติของมัน
หวังว่านี่จะช่วยได้
โปรดจำไว้ว่าคุณสามารถใช้วิธีการต่างๆรวมกันได้ นี่คือตัวอย่างการใช้แผนที่แบบอินไลน์ของการกระทำกับ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
ฟังก์ชั่นเป็นกล่าวอีกนัยหนึ่งเราไม่ได้สนใจว่ามันเป็นประเภทอะไร
หวังว่าจะช่วยให้คุณทำงานกับ :)
(o.constructor === Number || s.constructor === Boolean)
) Anecdotally parseInt
และNaN
เป็นเครื่องมือที่เปราะบาง แต่ทรงพลัง เพียงจำไว้ว่า Not-a-Number ไม่ใช่ Not-a-Number และสามารถกำหนดไม่ได้
if(thing.call) { 'its a function'; }
if(thing.defineProperties) { 'its an object'; }
ขอบคุณสำหรับการป้อนข้อมูล axkibe!
ฉันไม่สามารถเห็นได้อย่างจริงใจว่าทำไมไม่มีใครใช้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'));
ฉันชอบที่จะใช้วิธีแก้ปัญหาง่ายๆนี้:
var myString = "test";
if(myString.constructor === String)
{
//It's a string
}
undefined
และnull
และยังคงได้รับคำตอบที่ถูกต้องสำหรับสตริงว่าง (ทั้ง''
และnew String('')
)
(mystring || false) && mystring.constructor === String
ไม่มีปัญหา: ฉันใช้ false ในกรณีที่ใช้ในฟังก์ชันที่ต้องส่งคืนบูลีน
นี่เป็นตัวอย่างที่ดีว่าทำไมประสิทธิภาพจึงสำคัญ:
การทำอะไรที่ง่ายเหมือนการทดสอบสตริงอาจมีราคาแพงถ้าทำไม่ถูกต้อง
ตัวอย่างเช่นถ้าฉันต้องการเขียนฟังก์ชั่นเพื่อทดสอบว่าบางอย่างเป็นสตริงฉันสามารถทำได้ด้วยวิธีใดวิธีหนึ่งจากสองวิธี:
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
typeof str === 'string' || str instanceof String
(สามารถวางวงเล็บซึ่งฉันชอบในif (..)
บางกรณี); ไม่ว่าการตรวจสอบทั้งชนิดดั้งเดิมและชนิดของวัตถุใน # 2 นั้นชัดเจนและเพียงพอ เช็คเหล่านี้ควรจะ 'หายาก' อยู่ดี
if (s && typeof s.valueOf() === "string") {
// s is a string
}
ใช้งานได้ทั้งตัวอักษรสตริงlet s = 'blah'
และ Object Stringslet s = new String('blah')
นำมาจาก 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
ฉันคิดว่าโซลูชัน @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)
และด้วยการรวมกลุ่มที่เรียบง่ายคุณควรจะใช้ได้ (ฉันอ้างถึงที่นี่เพื่อรหัสลูกค้า)
หากคุณทำงานกับสภาวะแวดล้อม node.js คุณสามารถใช้ฟังก์ชัน built-in isString ใน utils
const util = require('util');
if (util.isString(myVar)) {}
แก้ไข: ดังที่ @Jehy กล่าวถึงสิ่งนี้เลิกใช้แล้วตั้งแต่ v4
typeof value === 'string'
แทน"
x = new String('x'); x.isString(x);
ผลตอบแทนที่เป็นเท็จ มีutil.types.isStringObject()
แต่ที่ส่งกลับเท็จสำหรับx = 'x'
สตริงประเภท สองฟังก์ชั่นยูทิลิตี้ที่ไม่ได้ให้ยูทิลิตี้อย่างแน่นอน ...
วิธีการต่อไปนี้จะตรวจสอบว่าตัวแปรใด ๆ เป็นสตริง ( รวมถึงตัวแปรที่ไม่มีอยู่ )
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
ฉันก็พบว่ามันใช้งานได้ดีเช่นกันและมันสั้นกว่าตัวอย่างอื่นมาก
if (myVar === myVar + '') {
//its string
} else {
//its something else
}
โดยเชื่อมต่อกับคำพูดที่ว่างเปล่ามันจะเปลี่ยนค่าเป็นสตริง หากmyVar
เป็นสตริงอยู่แล้วข้อความสั่ง if จะสำเร็จ
typeof
ฉัน
typeof
toString
ทั้งสองวิธีฉันเดาว่าฉันชอบไวยากรณ์สำหรับการข่มขู่
var s = new String('abc'); > s === s + '' > false
new String
w3schools.com/js/tryit.asp?filename=tryjs_string_object2object
var a = new String('')
var b = ''
var c = []
function isString(x) {
return x !== null && x !== undefined && x.constructor === String
}
console.log(isString(a))
console.log(isString(b))
console.log(isString(c))
false
มันจะโยนความผิดพลาดที่ไม่ได้ผลิต
ฉันพบเทคนิคง่าย ๆ นี้มีประโยชน์ในการพิมพ์ตรวจสอบสำหรับ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
จะส่งคืนสำหรับสิ่งที่เป็นสตริงเสมอ
function isClass(x,re){return ({}).toString.call(x).search(re)>0;};
isClass("hello",/String/)
หรือisClass(3,/Number/)
หรือisClass(null,/Null/)
ทางออกที่ง่ายจะเป็น:
var x = "hello"
if(x === x.toString()){
// it's a string
}else{
// it isn't
}
toString()
ฟังก์ชั่น
.toString
ค่าใด ๆ ลองถ้า x ที่จะตรวจสอบเป็นโมฆะหรือไม่ได้กำหนดรหัสของคุณโยนข้อยกเว้น
toString()
วิธีการอาจถูกเขียนทับและอาจทำให้เกิดข้อยกเว้น (เนื่องจากมีการใช้งานบางอย่าง) และเช็คของคุณจะไม่ทำงานอย่างแน่นอน แนวคิดหลักคือคุณไม่ควรเรียกวิธีการที่ไม่เกี่ยวข้องกับสิ่งที่คุณต้องการรับ ฉันไม่ได้พูดถึงค่าใช้จ่ายที่ไม่จำเป็นที่เกี่ยวข้องกับtoString
วิธีการ downvoting
ผู้ช่วย 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
)
ฉันจะไปเส้นทางที่แตกต่างไปยังส่วนที่เหลือที่นี่ซึ่งพยายามที่จะบอกว่าตัวแปรเป็นเฉพาะหรือเป็นสมาชิกของประเภทชุดที่เฉพาะเจาะจง
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('');
}
}
รวมเป็นตัวเลือก
.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});
เอาท์พุท:
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"
เพียงเพื่อขยายคำตอบของ @ 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
และประเภทและมันจะดูแลประเภทที่ไม่ใช่สตริงเช่นundefined
0
มันดีพอสำหรับฉัน
คำเตือน:นี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบ ดูที่ด้านล่างของโพสต์ของฉัน
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
คุณสามารถใช้ฟังก์ชั่นนี้เพื่อกำหนดประเภทของอะไร:
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
ฉันไม่แน่ใจว่าคุณหมายถึงการรู้ว่ามันเป็นประเภทใดstring
โดยไม่คำนึงถึงเนื้อหาของมันหรือว่าเนื้อหานั้นเป็นตัวเลขหรือสตริงไม่ว่าจะเป็นประเภทใด
ดังนั้นเพื่อทราบว่าประเภทของมันคือสตริงหรือไม่นั้นได้รับการตอบแล้ว
แต่รู้ตามเนื้อหาถ้าเป็นสตริงหรือตัวเลขฉันจะใช้นี้
function isNumber(item) {
return (parseInt(item) + '') === item;
}
และสำหรับบางตัวอย่าง:
isNumber(123); //true
isNumber('123'); //true
isNumber('123a');//false
isNumber(''); //false
/^\d+$/.test('123')
เพื่อหลีกเลี่ยงความซับซ้อนของปัญหาการแยกวิเคราะห์ที่อาจเกิดขึ้น)