强制Protobuf.js忽略无法识别的JS端字段

时间:2015-04-23 17:24:07

标签: typescript protocol-buffers

在JS(实际上是TypeScript)和.NET w / protobuf.js之间来回发送对象时,我想装饰JS对象w /仅在运行时有意义的字段(例如WebGL上下文,句柄等)。添加新的动态字段非常简单:

ReceivedObject.RuntimeField = new RuntimeField();

但是,当序列化回服务器时,protobuf.js会发现新字段并引发异常。

我发现我可以通过将以下三行直接添加到protobuf.js来解决这个问题:

MessagePrototype.set = function (keyOrObj, value, noAssert) {
    if (keyOrObj && typeof keyOrObj === 'object') {
        noAssert = value;
        for (var ikey in keyOrObj)
            if (keyOrObj.hasOwnProperty(ikey) && typeof (value = keyOrObj[ikey]) !== 'undefined') {
                if (ikey == "RuntimeField") {   // added
                    continue;                   // added    
                }                               // added
                this.$set(ikey, value, noAssert);
            }
        return this;
    }
    ...
}

这当然不是很容易维护。有更好的方法吗?对象层次结构丰富而深入,因此我希望避免涉及从自定义JS端对象批量复制100多个字段的方法。

感谢您的任何建议。

1 个答案:

答案 0 :(得分:2)

我为你创建了一个简短的例子。您可以使用Object.defineProperty来解决此问题,以添加不可枚举的属性(当您使用for (var key in obj)时,这不会显示。

在下面的示例中,first属性是可枚举的(并且将与name属性一起显示在控制台窗口中)。 second属性不可枚举,因此不会出现在控制台窗口中。

使用此技术,您可以添加for循环中无法获取的属性。

var obj = {
    name: 'Steve'
};

Object.defineProperty(obj, 'first', {
  enumerable: true,
  value: 'example'
});

Object.defineProperty(obj, 'second', {
  enumerable: false,
  value: 'example'
});

for (var key in obj) {
    if (obj.hasOwnProperty(key) 
        && typeof (value = obj[key]) !== 'undefined') {

        console.log(key);   
    }
}

因此,要将此与您的具体问题联系起来,您可以使用...

Object.defineProperty(ReceivedObject, 'RuntimeField', {
  enumerable: false,
  value: new RuntimeField()
});