javascript中类型的默认值

amr*_*rk7 8 javascript types default-value

JavaScript中是否有一个函数返回传递给它的类型名称的默认值?例如:

var defaultValue = built_in_getDefaultValue("number");
console.log(defaultValue); // Logs the number 0 to the console.
Run Code Online (Sandbox Code Playgroud)

Jor*_*ray 12

这两个答案都正确地指出JavaScript中变量的默认(未分配)值是undefined,但是它们都没有解决您看起来要寻找的问题 - 相当于例如defaultC#中的运算符.

幸运的是,JavaScript有一个非常简单的类型系统:不是六种基本类型之一(ES5中的五种)的所有东西都是一个对象,可以通过它的构造函数来调用.给出一个字符串表示以下函数

  • JS原语的名称;
  • 任何有效的typeof经营者生产; 要么
  • 函数名称,可以this是调用它的值,也可以是本地范围¹

将产生对"默认"值的合理解释:

function defaultVal(type) {
    if (typeof type !== 'string') throw new TypeError('Type must be a string.');

    // Handle simple types (primitives and plain function/object)
    switch (type) {
        case 'boolean'   : return false;
        case 'function'  : return function () {};
        case 'null'      : return null;
        case 'number'    : return 0;
        case 'object'    : return {};
        case 'string'    : return "";
        case 'symbol'    : return Symbol();
        case 'undefined' : return void 0;
    }

    try {
        // Look for constructor in this or current scope
        var ctor = typeof this[type] === 'function'
                   ? this[type]
                   : eval(type);

        return new ctor;

    // Constructor not found, return new object
    } catch (e) { return {}; }
}
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它:

defaultVal( typeof 1 ); // -> 0
defaultVal( 'number' ); // -> 0
defaultVal( 'object' ); // -> {}
defaultVal( 'RegExp' ); // -> /(?:)/
Run Code Online (Sandbox Code Playgroud)

不幸的是,JS typeof运营商可能有点......为我们的目的.例如,typeof null === 'object'typeof [] === 'object',这可能不是你想要的.

要解决这个问题,这里有一个函数,它返回调用typeof值的结果,除非结果是'object',在这种情况下,'null'如果值为,则返回它null,obj.constructor.name否则( 'object'如果所有其他方法都失败则返回后退值):

function getType(obj) {
    var type = typeof obj;

    if (type !== 'object') return type; // primitive or function
    if (obj === null) return 'null';    // null

    // Everything else, check for a constructor
    var ctor = obj.constructor;
    var name = typeof ctor === 'function' && ctor.name;

    return typeof name === 'string' && name.length > 0 ? name : 'object';
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以:

defaultVal( getType( 1234 ) );  // -> 0
defaultVal( getType( [99] ) );  // -> []
defaultVal( getType( 'ab' ) );  // -> ""
defaultVal( getType( null ) );  // -> null   (Not possible with typeof!)
defaultVal( getType( /.*/ ) );  // -> /(?:)/ (Not possible with typeof!)

function T () {}
defaultVal( getType( new T ) ); // -> T {}   (Not possible with typeof!)
Run Code Online (Sandbox Code Playgroud)

我怀疑这与你想要得到的一样接近.另外,要避免任何批评:上面使用eval可能看起来有点脏,但这是从当前范围获取命名值的唯一方法.


¹此函数无法调用在另一个范围内实例化的构造函数; 相反,我已经可以通过this绑定到包含它可能引用的任何此类构造函数的对象来调用它:

function innerScopeCtor() {
    function T () {}

    return defaultVal.call( { T : T }, 'T' );
}

innerScopeCtor(); // T {}
Run Code Online (Sandbox Code Playgroud)

如果你不这样做,它将回退到返回一个新对象.


Den*_*ret 0

JavaScript 中任何变量的默认值都是undefined。您也可以将其作为

var defaultValue = void 0;
Run Code Online (Sandbox Code Playgroud)