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


86

是否可以将某些字段排除在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 }

我想在其中没有privateproperties的字符串。



4
而不是返回“ none”,而不是返回undefined。
JoeyRobichaud 2011年

1
我看到了这个问题,我不想删除属性,因为它会影响当前的应用程序。我试图将对象保存到文件中,而应用程序仍然具有活动对象,因此删除属性将使其无用。另一个选择是我可以克隆对象,删除字段,然后将克隆对象字符串化。
Nilesh

1
嘿乔,太好了。未定义的技巧。谢谢。我将更新问题
Nilesh

Answers:


100

Mozilla的文档说回报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'])));

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


33

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

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

我投票支持这种做法,因为我觉得这是..更优雅
罗密欧塞拉利昂

17

您可以使用Object的本机函数defineProperty

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

11
该答案有效,因为enumerable此属性描述符的值为false。
Soul_Master

注意:如果数据是一个数组并且想要隐藏它的第n个元素,则它不起作用。
AlexSzücs

3

更简单的方法。

  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


2

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

2

请注意Miroslaw Dylag答案:定义的属性应该是自己的财产。否则它将失败。

不起作用:

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)

1

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

如果使用函数分配它,它将不会包含在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

您也可以尝试使用该概念,即使不在固定对象上也可以。


仅当您不需要设置该属性的值时,此方法才有效。
加百利C


0

您可以使用ES2017轻松完成

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

在这里privateProperty1privateProperty2被分配给exc1exc2据此。其余的分配给foo新创建的变量



0

尽管没有Internet Explorer支持,但这是另一种方法。

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

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

0

这是一个古老的问题,但是我要添加一个答案,因为有一个更简单的方法可以解决这个问题。传递要在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"}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.