9

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

var defaultValue = built_in_getDefaultValue("number");
console.log(defaultValue); // Logs the number 0 to the console.
4

3 回答 3

15

先前的两个答案都正确地指出,JavaScript 中变量的默认(未分配)值是undefined,但都没有解决您似乎正在寻找的内容 - 相当于defaultC# 中的运算符。

幸运的是,JavaScript 有一个非常简单的类型系统:所有不是七种原始类型之一的东西都是一个对象,可以通过它的构造函数调用。¹下面的函数,给定一个字符串表示

  • JS 原始类型的名称,例如'string'or 'null';
  • 操作员的任何有效产品typeof,例如'function'
  • 函数名称在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 'bigint'    : return BigInt(0);
        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 {}; }
}

你可以这样称呼它:

defaultVal( typeof 1 ); // -> 0
defaultVal( 'bigint' ); // -> 0n
defaultVal( 'object' ); // -> {}
defaultVal( 'RegExp' ); // -> /(?:)/

不幸的是,typeof对于我们的目的来说,JS 操作符可能有点……anameic。例如,typeof null === 'object'¹ 和typeof [] === 'object',这可能不是您想要的。

为了解决这个问题,这里有一个函数,它返回调用typeof一个值的结果,除非'null'结果是'object',在这种情况下,如果值是,它将返回nullobj.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';
}

现在我们可以拥有:

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

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


¹null有点奇怪。ECMAScript 2020 规范明确将其称为原语;但是,typeof null这是'object'由于原始 JavaScript 实现中的错误造成的。有一次,MDN 从它的原语列表中排除了 null,只计算了六个原语,并声明null应该将其视为“每个元素的特殊情况Object”。

根据规范,我null在此答案中将其称为原语,并且 MDN 已更新以同意此立场。

² 该函数不能调用在另一个作用域中实例化的构造函数;相反,我可以通过this绑定到包含它可能引用的任何此类构造函数的对象来调用它:

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

innerScopeCtor(); // T {}

如果你不这样做,它只会退回到返回一个新对象。

于 2015-02-25T00:03:36.557 回答
1

我不明白你为什么要问这样的问题。无论如何,JavaScript 中变量的默认值为nullundefined

出于学习目的,我从 WikiBooks JavaScript/Variables and Types中获取了这个:

变量通常由 var 语句显式声明,如下所示:

var c;

上述变量已创建,但默认值为undefined. 为了有价值,变量需要初始化:

var c = 0;

声明后,可以为变量分配一个新值,该值将替换旧值:

c = 1;

但是请确保在分配给它之前(或同时)使用 var 声明一个变量;否则您将创建一个“范围错误”。

现在,当你问为什么这个值不是0时,那是因为,甚至null或者undefined是没有定义的值。未定义不同于已定义和为空。0当值被声明但未定义时,它可能会返回。

于 2013-01-30T11:40:05.153 回答
0

javascript 中任何变量的默认值都是undefined. 你也可以得到它

var defaultValue = void 0;
于 2013-01-30T11:38:52.837 回答