如何验证变量是否为Enum?

时间:2019-05-09 07:08:11

标签: javascript google-apps-script types enums instance

我希望检查变量是否为有效的Google App Script Enum type

function myFunc(BORDER_COLOR) {
    if (typeof BORDER_COLOR !== "Enum") {    // This does not work
        // do something for this exception
    }
    // rest of the function
}

我使用typeofinstanceof进行检查。但是有些奇怪的事情发生了。 Enum是一个对象。但这不是Object的实例。这与我的理解相矛盾。

  • 我想所有原始类型(字符串,布尔值等)都是非对象。
  • 我认为所有非基本类型(数组,用户定义的类型等)都是对象。
  • 为什么?

Logger.log(typeof SpreadsheetApp.BorderStyle.SOLID);             // object
Logger.log(SpreadsheetApp.BorderStyle.SOLID instanceof Object);  // false <-- unexpected
Logger.log("");

var value = "text";
Logger.log(typeof value);               // string
Logger.log(value instanceof Object);    // false
Logger.log("");

var value = new String("text");
Logger.log(typeof value);               // object
Logger.log(value instanceof Object);    // true
Logger.log("");

Logger.log(Array instanceof Object);    // true
Logger.log(Object instanceof Object);   // true

添加:

var value = 123;
Logger.log(typeof value);               // number
Logger.log(TYPEOF(value));              // number
Logger.log(value instanceof Object);    // false
Logger.log("");

var value = [];
Logger.log(typeof value);               // object
Logger.log(TYPEOF(value));              // Array[0]
Logger.log(value instanceof Object);    // true
Logger.log("");

var value = {};
Logger.log(typeof value);               // object
Logger.log(TYPEOF(value));              // Object
Logger.log(value instanceof Object);    // true
Logger.log("");

function TYPEOF(value) {
  if (typeof value !== 'object')    // not an object, it is a primitive type
    return typeof value;

  var details = '';
  if (value instanceof Array) {            // if this is an object, may be this is an Array
    details += '[' + value.length + ']';
    if (value[0] instanceof Array)
      details += '[' + value[0].length + ']';
  }

  var className = value.constructor ? value.constructor.name : value.constructor;   // if this is not an Array, get the (tailor-made) constructor name
  return className + details;
}

1 个答案:

答案 0 :(得分:0)

使用Object.keys()查看是否有可用于验证的内容。我发现最有价值的是nameordinal。因此,最简单的检查是查看是否可以在枚举上调用name()

function test() {
  Logger.log(Object.keys(SpreadsheetApp.BorderStyle.DASHED)); // [name, toString, compareTo, ordinal]
  Logger.log(SpreadsheetApp.BorderStyle.DASHED.name()); // DASHED
  Logger.log("name" in SpreadsheetApp.BorderStyle.DASHED); // true

  try {  
    if ("name" in SpreadsheetApp.BorderStyle.DASHED) { // This is true
      Logger.log("SpreadsheetApp.BorderStyle.DASHED is valid enum"); // This should print
    }
  } catch (err) {}; 

  try {
    if ("name" in SpreadsheetApp.BorderStyle.NOT_VALID) { // This errors
      Logger.log("SpreadsheetApp.BorderStyle.NOT_VALID is not a valid enum"); // Will not print
    }
  } catch (err) {
    Logger.log("Errored");
  };
}

这样,您就可以创建一个更通用的函数来测试SpreadsheetApp中的枚举值(或适用于其他服务)。实际上,因为传递了属性名称,所以我们可以比较名称来放心地检查它是否为枚举,而不是仅检查in,对于原型链中的属性也返回true。

/**
 * Check if the type and property are a valid Enum of the SpreadsheetApp.
 * @param {String} type
 * @param {String} property
 * @returns {Boolean}
 */
function isSpreadsheetEnum(type, property) {
  try {
    return SpreadsheetApp[type][property].name() === property;
  } catch (err) {
    return false;
  }
}

您可以这样使用:

function testEnum() {
  Logger.log(isSpreadsheetEnum("DataValidationCriteria", "DATE_ON_OR_AFTER"));
}