javascript - 你能检查未实例化的 JS 对象的字段名称和类型吗?

标签 javascript node.js

我想检查一个输入对象以确保它是我期望的形式,而不必实例化一个新对象;这可能吗?

我期待一个 Point 对象。有效的 Point 对象如下所示:

{
   name: "Point name",
   x: 32,
   y: 98
}

我有一个函数可以从我无法控制的源获取一些输入:

function(inputObject) {
   if (!(inputObject instanceof Point)) return false;
   // check fields existence and types
}

我想确保这三个字段都存在,并且它们的类型与有效的Point相同,即字符串、数字、数字。这将检查大量点,因此我想避免每次都创建一个新点来检查,我怎样才能实现这一点?

最佳答案

您应该注意检查输入值的严格程度。 Javascript 是松散类型的,因此虽然您可能会为 point.x 分配一个数字,但在某些时候它可能会被分配一个字符串。

您可以根据如下测试拒绝:

if (typeof point.x != 'number') {
  // bad point
}

但是,更好的策略可能是在分配值时确保正确的类型。

instanceof 运算符对于确保值的类型正确无用(因为类型完全基于分配值的类型,而不是继承),并且在构造函数和实例所在的位置会失败来自不同的全局执行上下文(例如跨帧)。还可以通过修改对象的[[Prototype]]构造函数属性来破坏它。

编辑

如果您想验证一个对象是否是一个点,并且不想创建一个新点来测试,您可以创建一个包含实例闭包的 isPoint 方法,并且对此进行测试(或使用一些类似的策略):

function Point(name, x, y) {
  this.name = name;
  this.x = x;
  this.y = y;
}

Point.prototype.vectorLength = function() {
  return Math.sqrt(x*x + y*y);
}

Point.isPoint = (function() {
  var point = new Point('name', 0, 0);
  return function(obj) {
    for (var prop in point) {
      if (!(prop in obj) && typeof point[prop] != typeof obj[prop]) {
        return false;
      }
    }
    return true;
  };
}());

var a = new Point('a',0,0);

alert(Point.isPoint(a)); // true

alert(Point.isPoint({name:'b', x:0, y:0})); // false, no inherited vectorLength method

但是,这些都不能确保属性值具有特定的类型,因为 setter 方法可能更健壮。

关于javascript - 你能检查未实例化的 JS 对象的字段名称和类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21105257/

相关文章:

php - xmlHttp 字符串传递

node.js - nodejs Firestore突然崩溃: Date objects

node.js - 在 Docker 容器中运行和调试测试

node.js - 如何修复 'fs: re-evaluating native module sources is not supported' - 优雅的 fs

javascript - Node-Webkit (nwjs) Node 远程用法

javascript - 一个组件可以接收两个 HOC 的数据吗?

javascript - 如何使用 javascript 或 jquery 将时间转换为 javascript-timestamps?

node.js - 如何在nodejs中用swig输出JSON

javascript - 使用 NodeJs 和 MongoDB 存储事件的最佳实践是什么

Javascript - 用于删除特殊字符但还保留希腊字符的正则表达式