Javascript 在 JSON.stringify() 的输出中隐藏某些值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4910567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:43:11  来源:igfitidea点击:

Hide certain values in output from JSON.stringify()

javascriptjson

提问by Nilesh

Is it possible to exclude certain fields from being included in the json string?

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

Here is some pseudo code

这是一些伪代码

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

I want to exclude privateProperty1 and privateproperty2 from appearing in the json string

我想从 json 字符串中排除 privateProperty1 和 privateproperty2

So I thought, I can use the stringify replacer function

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

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

and in the stringify

并在字符串化

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

But in the jsonString I still see it as

但在 jsonString 我仍然认为它是

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

I would like to the string without the privateproperties in them.

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

回答by Jared Farrish

The Mozilla docssay to return undefined(instead of "none"):

Mozilla的文档说回报undefined(而不是"none"):

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

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));

Here is a duplication method, in case you decide to go that route (as per your comment).

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

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

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- I changed the function key in the bottom function to keep it from being confusing.

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

回答by Curtis Yallop

Another good solution: (requires underscore)

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

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

The benefit of this solution is that anyone calling JSON.stringify on x will have correct results - you don't have to alter the JSON.stringify calls individually.

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

Non-underscore version:

非下划线版本:

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

回答by Miroslaw Dylag

You can use native function definePropertyfrom Object:

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

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

回答by Markandey Singh

Easier way to do.

更简单的方法。

  1. Create a variable and assign an empty array. This makes object to be the prototype of array.
  2. Add non numeric keys on this object.
  3. Serialize this object using JSON.stringify
  4. You will see that nothing is serialized from this object.
  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

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

回答by Matan Hafuta

Object.create is another solution that is close to the defineProperty solution (properties are defined in the same way) but in this way you define the properties to expose from the beginning. In this way you can expose only the properties that you want by setting the property enumerablevalue to true (false by default), JSON.stringify is ignoring non-enumerable properties, the downside is that this property will also be hidden when using for-in loop on the object or functions like Object.keys.

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"}"

回答by Audi Nugraha

Note for Miroslaw Dylag's answer: The defined property should be its own property. Otherwise it would fail.

注意Miroslaw Dylag回答:定义的属性应该是它自己的属性。否则就会失败。

Doesn't work:

不起作用:

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)

Works:

作品:

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)

回答by Carlos Arturo Alaniz

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;
    };
}

回答by peja

you can do it easily with ES2017

您可以使用 ES2017 轻松完成

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

Here privateProperty1and privateProperty2are assigned to exc1and exc2accordingly. The remainings are assigned to foonewly created variable

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

回答by Yacine

I've used toJSON solution based on a small library that i've written in order to get Typing at Runtime https://stackoverflow.com/a/55917109/4236151

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

回答by Mike Nikles

Here's another approach, although without Internet Explorer support.

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

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

const jsonString = JSON.stringify(x, excludePrivateProperties);