如何确定变量是字符串还是JavaScript中的其他变量?


当前回答

从lodash库v4.0.0实现

// getTag.js

const toString = Object.prototype.toString;

/**
 * Gets the `toStringTag` of `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
function getTag(value) {
    if (value == null) {
        return value === undefined 
            ? "[object Undefined]" 
            : "[object Null]";
    }
    return toString.call(value);
}
// isString.js

import getTag from "./getTag.js";

/**
 * Checks if `value` is classified as a `String` primitive or object.
 *
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
 * @example
 *
 * isString('abc')
 * // => true
 *
 * isString(1)
 * // => false
 */
function isString(value) {
    const type = typeof value;
    return (
        type === "string" || (type === "object" &&
                              value != null &&
                              !Array.isArray(value) &&
                              getTag(value) == "[object String]")
    );
}

export default isString;

其他回答

您可以使用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]使用。如果您愿意,请查看其他答案以了解如何处理这些问题。


谷歌JavaScript风格指南说,永远不要使用原始对象包装器。Douglas Crockford建议弃用基本对象包装器。

这是一个很好的例子,说明了为什么性能很重要:

如果做得不正确,对字符串进行测试这样简单的操作可能会很昂贵。

例如,如果我想写一个函数来测试某个东西是否是字符串,我可以用以下两种方法之一:

1) const isString=str=>(Object.pr原型.toString.call(str)=='[Object String]');

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

这两个都非常直接,那么什么可能会影响性能呢?一般来说,函数调用可能会很昂贵,特别是如果您不知道内部发生了什么。在第一个示例中,有一个对Object的toString方法的函数调用。在第二个示例中,没有函数调用,因为typeof和instanceof是运算符。运算符比函数调用快得多。

测试性能时,示例1比示例2慢79%!

参见测试:https://jsperf.com/isstringtype

这对我来说已经足够好了。

警告:这不是一个完美的解决方案。请看我帖子的底部。

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

为了扩展@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和未定义的类型,并将处理非字符串类型,例如0。

isString()使用可选链接和最新标准检查传递的参数是否为字符串:

const isString = (value) => { 
    return value?.constructor === String;
}