【问题标题】:Hide certain values in output from JSON.stringify()在 JSON.stringify() 的输出中隐藏某些值
【发布时间】:2011-06-22 02:05:00
【问题描述】:

是否可以排除某些字段不包含在 json 字符串中?

这是一些伪代码

var x = {
    x:0,
    y:0,
    divID:"xyz",
    privateProperty1: 'foo',
    privateProperty2: 'bar'
}

我想排除 privateProperty1 和 privateproperty2 出现在 json 字符串中

所以我想,我可以使用 stringify 替换函数

function replacer(key,value)
{
    if (key=="privateProperty1") then retun "none";
    else if (key=="privateProperty2") then retun "none";
    else return value;
}

并在字符串化中

var jsonString = json.stringify(x,replacer);

但在 jsonString 我仍然认为它是

{...privateProperty1:value..., privateProperty2:value }

我想要其中没有私有属性的字符串。

【问题讨论】:

  • 而不是返回“none”返回未定义。
  • 我看到了这个问题,我不想删除属性,因为它会影响我当前的应用程序。我正在尝试将对象保存到文件中,并且应用程序仍然具有活动对象,因此删除属性将使其无用。另一种选择是我可以克隆对象,删除字段,然后对克隆对象进行字符串化。
  • 嗨,乔,太好了。未定义的成功了。谢谢。我会更新问题

标签: javascript json


【解决方案1】:

Mozilla docs 表示返回undefined(而不是"none"):

http://jsfiddle.net/userdude/rZ5Px/

function replacer(key,value)
{
    if (key=="privateProperty1") return undefined;
    else if (key=="privateProperty2") return undefined;
    else return value;
}

var x = {
    x:0,
    y:0,
    divID:"xyz",
    privateProperty1: 'foo',
    privateProperty2: 'bar'
};

alert(JSON.stringify(x, replacer));

这是一种复制方法,以防您决定走那条路(根据您的评论)。

http://jsfiddle.net/userdude/644sJ/

function omitKeys(obj, keys)
{
    var dup = {};
    for (var key in obj) {
        if (keys.indexOf(key) == -1) {
            dup[key] = obj[key];
        }
    }
    return dup;
}

var x = {
    x:0,
    y:0,
    divID:"xyz",
    privateProperty1: 'foo',
    privateProperty2: 'bar'
};

alert(JSON.stringify(omitKeys(x, ['privateProperty1','privateProperty2'])));

EDIT - 我更改了底部功能中的功能键,以免混淆。

【讨论】:

    【解决方案2】:

    另一个很好的解决方案:(需要下划线)

    x.toJSON = function () {
        return _.omit(this, [ "privateProperty1", "privateProperty2" ]);
    };
    

    此解决方案的好处是任何人在 x 上调用 JSON.stringify 都会得到正确的结果 - 您不必单独更改 JSON.stringify 调用。

    非下划线版本:

    x.toJSON = function () {
        var result = {};
        for (var x in this) {
            if (x !== "privateProperty1" && x !== "privateProperty2") {
                result[x] = this[x];
            }
        }
        return result;
    };
    

    【讨论】:

    • 我投票赞成这种方法,因为我发现它更优雅..
    【解决方案3】:

    您可以使用 Object 的原生函数 defineProperty

    var data = {a: 10};
    Object.defineProperty(data, 'transient', {value: 'static', writable: true});
    data.transient = 'dasda';
    console.log(JSON.stringify(data)); //{"a":10}
    

    【讨论】:

    • 此答案有效,因为此属性描述符的 enumerable 值为 false。
    • 注意:如果数据是一个数组并且想要隐藏它的第n个元素,则它不起作用。
    【解决方案4】:

    这是一个老问题,但我要添加一个答案,因为有一种更简单的方法可以解决这个问题。传递您希望在 JSON 中输出的字符串数组。

    var x = {
        x:0,
        y:0,
        divID:"xyz",
        privateProperty1: 'foo',
        privateProperty2: 'bar'
    }
    
    JSON.stringify(x, ["x", "y", "divID"]);
    
    // This will output only x y and divID
    // {"x":0,"y":0,"divID":"xyz"}

    【讨论】:

      【解决方案5】:

      这是我使用扩展运算符 (...) 的方法:

      const obj = {
        name: "hello",
        age: 42,
        id: "3942"
      };
      
      const objWithoutId = { ...obj, id: undefined };
      
      const jsonWithoutId = JSON.stringify(objWithoutId);
      
      console.log(jsonWithoutId);

      【讨论】:

        【解决方案6】:

        更简单的方法。

        1. 创建一个变量并分配一个空数组。这使得对象成为数组的原型。
        2. 在该对象上添加非数字键。
        3. 使用 JSON.stringify 序列化此对象
        4. 您将看到该对象没有序列化任何内容。

        ~~~

        var myobject={
          a:10,
          b:[]
        };
        
        myobject.b.hidden1 = 'hiddenValue1';
        myobject.b.hidden2 = 'hiddenValue2';
        
        //output of stringify 
        //{
        //    "a": 10,
        //    "b": []
        //}
        

        ~~~

        http://www.markandey.com/2015/07/how-to-hide-few-keys-from-being-being.html

        【讨论】:

          【解决方案7】:

          Object.create 是另一个接近于 defineProperty 解决方案的解决方案(属性以相同的方式定义),但通过这种方式,您可以从头开始定义要公开的属性。 这样你就可以通过设置属性enumerable值为true(默认为false)只暴露你想要的属性,JSON.stringify是忽略不可枚举的属性,缺点是这个属性在使用的时候也会被隐藏对象上的 for-in 循环或 Object.keys 等函数。

          var x = Object.create(null, {
              x: {value:0, enumerable: true}, 
              y:{value: 0, enumerable: true}, 
              divID: {value: 'xyz', enumerable: true}, 
              privateProperty1: {value: 'foo'}, 
              privateProperty2: {value: 'bar'}
          });
          JSON.stringify(x)
          //"{"x":0,"y":0,"divID":"xyz"}"
          

          【讨论】:

            【解决方案8】:

            Miroslaw Dylaganswer 的注意事项:定义的属性应该是它自己的属性。否则会失败。

            不起作用:

            class Foo {
            }
            Object.defineProperty(Foo.prototype, 'bar', { value: 'bar', writable: true });
            
            const foo = new Foo();
            foo.bar = 'baz';
            alert(JSON.stringify(foo).indexOf('bar') === -1); // false (found)
            

            作品:

            class Foo {
              constructor() {
                Object.defineProperty(this, 'bar', { value: 'bar', writable: true });
              }
            }
            
            const foo = new Foo();
            foo.bar = 'baz';
            alert(JSON.stringify(foo).indexOf('bar') === -1); // true (not found)
            

            【讨论】:

              【解决方案9】:

              我知道这已经是一个已回答的问题,但我想在使用实例化对象时添加一些内容。

              如果使用函数分配它,它不会包含在 JSON.stringify() 结果中。

              要访问该值,也可以将其作为函数调用,以() 结尾

              var MyClass = function(){
                  this.visibleProperty1 = "sample1";
                  this.hiddenProperty1 = function(){ return "sample2" };
              }
              
              MyClass.prototype.assignAnother = function(){
                  this.visibleProperty2 = "sample3";
                  this.visibleProperty3 = "sample4";
                  this.hiddenProperty2 = function(){ return "sample5" };
              }
              
              var newObj = new MyClass();
              console.log( JSON.stringify(newObj) );
              // {"visibleProperty1":"sample1"}
              
              newObj.assignAnother();
              console.log( JSON.stringify(newObj) );
              // {"visibleProperty1":"sample1","visibleProperty2":"sample3","visibleProperty3":"sample4"}
              
              console.log( newObj.visibleProperty2 ); // sample3
              console.log( newObj.hiddenProperty1() ); // sample2
              console.log( newObj.hiddenProperty2() ); // sample5
              

              即使不在实体对象上,您也可以玩转这个概念。

              【讨论】:

              • 这仅在您不需要设置该属性的值时才有效。
              【解决方案10】:

              这是另一种方法,虽然没有 Internet Explorer 支持。

              const privateProperties = ["privateProperty1", "privateProperty2"];
              const excludePrivateProperties = (key, value) => privateProperties.includes(key) ? undefined : value;
              
              const jsonString = JSON.stringify(x, excludePrivateProperties);
              

              【讨论】:

                【解决方案11】:
                abstract class Hideable {
                    public hidden = [];
                    public toJSON() {
                        var result = {};
                        for (var x in this) {
                            if(x == "hidden") continue;
                            if (this.hidden.indexOf(x) === -1) {
                                result[x] = this[x];
                            }
                        }
                        return result;
                    };
                }
                

                【讨论】:

                  【解决方案12】:

                  你可以使用 ES2017 轻松做到这一点

                  let {privateProperty1:exc1, privateProperty2:exc2, ...foo} = {
                      x:0,
                      y:0,
                      divID:"xyz",
                      privateProperty1: 'foo',
                      privateProperty2: 'bar'
                  }
                  

                  这里privateProperty1privateProperty2 被相应地分配给exc1exc2。剩下的分配给foo新创建的变量

                  【讨论】:

                    【解决方案13】:

                    我使用了基于我编写的一个小型库的 toJSON 解决方案,以便在运行时输入 https://stackoverflow.com/a/55917109/4236151

                    【讨论】:

                      【解决方案14】:

                      我订阅了delp的主题https://stackoverflow.com/a/62457745/14491024 这个主题对我的代码有帮助

                       JSON.stringify(GetMyContent[i], ["mdlPageName", "mdlAligen", "mdlOrderNumberHorizontal", "mdlPageId", "mdlOrderNumberVertical"])
                      

                      这样我可以选择我需要的属性:

                          if (GetMyContent[i].mdlAligen == "Left") {
                      
                              var getrownum = GetMyContent[i].mdlOrderNumberHorizontal;
                      
                              if ($('.Left div.row:eq(' + (getrownum - 1) + ')').children().length > 0) {
                      
                                  $('.Left div.row:eq(' + (getrownum - 1) + ')').append("<div id=" + GetMyContent[i].mdlPageId + " class=\"border border-secondary col\"  " + "data-atrrib=" + JSON.stringify(GetMyContent[i], ["mdlPageName", "mdlAligen", "mdlOrderNumberHorizontal", "mdlPageId", "mdlOrderNumberVertical"]) + ">" + GetMyContent[i].mdlPageContentHtml + buttonEDI + "</div>");
                              }
                              else {
                                  $('.Left div.row:last').html("<div id=" + GetMyContent[i].mdlPageId + " class=\"border border-secondary col\"  " + "data-atrrib=" + JSON.stringify(GetMyContent[i], ["mdlPageName", "mdlAligen", "mdlOrderNumberHorizontal", "mdlPageId", "mdlOrderNumberVertical"]) + ">" + GetMyContent[i].mdlPageContentHtml + buttonEDI + "</div>");
                      
                                      $(".Left .row:last").after($('.Left .row:eq(0)').clone().html(""));
                              }
                          }
                      

                      【讨论】:

                        【解决方案15】:

                        除了 toJSON 和替换器。一个简单的解决方法是将变量转换为“静态”变量。由于静态变量是作为原型变量添加的,因此它们不会出现在 JSON 字符串中。

                        注意:如果变量可以是静态变量,请使用此选项。

                        【讨论】:

                          【解决方案16】:

                          removes 是要省略的键数组。 space 对于漂亮的打印是可选的。

                          // typescript version
                          export function toJson<T>(me: T, removes?: (keyof T)[], space?: number): string {
                            return JSON.stringify(me, (k, v) => (removes?.some((r) => r === k) ? undefined : v), space);
                          }
                          
                          // javascript version
                          export function toJson(me , removes , space) {
                            return JSON.stringify(me, (k, v) => (removes?.some((r) => r === k) ? undefined : v), space);
                          }
                          

                          例子

                          const data = {name: "ali" ,age: "80"};
                          console.log(toJson(data, ["age"]))
                          
                          // output: {"name":"ali"}
                          

                          【讨论】:

                            猜你喜欢
                            • 2017-04-28
                            • 2021-02-04
                            • 2022-01-06
                            • 1970-01-01
                            • 1970-01-01
                            • 2022-06-16
                            • 2012-05-08
                            • 2015-10-20
                            • 1970-01-01
                            相关资源
                            最近更新 更多