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

Forcing Protobuf.js to ignore unrecognized JS-side fields

在 JS(实际上是 TypeScript)和带 .NET 的 .NET 之间来回发送对象 protobuf.js 我想装饰 JS 对象带仅在运行时有意义的字段(例如 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;
    }
    ...
}

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

感谢您的任何建议。

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

时不会出现此问题

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

使用此技术,您可以添加不会在 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()
});