Javascript 您能检查未实例化JS对象的字段名和类型吗?

Javascript 您能检查未实例化JS对象的字段名和类型吗?,javascript,node.js,Javascript,Node.js,我想检查一个输入对象,以确保它的形式符合我的预期,而不必实例化一个新对象;这可能吗 我期待一个点对象。有效的点对象如下所示: { name: "Point name", x: 32, y: 98 } 我有一个函数,可以从我无法控制的源中获取一些输入: function(inputObject) { if (!(inputObject instanceof Point)) return false; // check fields existence and typ

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

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

{
   name: "Point name",
   x: 32,
   y: 98
}
我有一个函数,可以从我无法控制的源中获取一些输入:

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

我想确保这三个字段都在那里,并且它们的类型与有效的
相同,即字符串、数字、数字。这将检查大量的点,因此我希望避免每次都创建一个新点进行检查,如何实现这一点?

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

if (typeof inputObject.name == "string" & typeof inputObject.x == "number" & typeof inputObject.y == "number")
{
  return true;
}
else
{
  return false;
}
您可以基于以下测试拒绝该点:

if (typeof point.x != 'number') {
  // bad point
}
但是,更好的策略可能是在分配值时确保正确的类型

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

编辑 如果要验证对象是否为点,并且不想创建新的点进行测试,则可以创建一个对实例具有闭包的isPoint方法,并根据该方法进行测试(或使用类似策略):


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

输入对象是一个对象。您可以使用
Object.keys
检查属性(或使用
hasOwnProerty
测试检查
中的<代码>实例of
不是特别可靠。您如何“每次都检查一个新点”?也许可以向我们展示您的尝试。@RobG我可以用它来确保inputObject字段是
的有效子集,我似乎需要
的键来匹配,而不是相反。我希望有更通用/动态的东西,即。,将输入对象与我期望的对象类型的构造函数进行比较。
如果(someBoolean){return true;}否则{return false;}
是反模式<代码>返回布尔值做了完全相同的事情。老实说,我把它们作为占位符放进去了,因为不知道函数是只返回布尔值还是将继续进行一些处理
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