JSON.stringify ()의 출력에서 ​​특정 값 숨기기


86

특정 필드가 json 문자열에 포함되지 않도록 제외 할 수 있습니까?

다음은 의사 코드입니다.

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

privateProperty1 및 privateproperty2가 json 문자열에 나타나지 않도록 제외하고 싶습니다.

그래서 stringify replacer 기능을 사용할 수 있다고 생각했습니다.

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

그리고 stringify에서

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

하지만 jsonString에서는 여전히

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

privateproperties가없는 문자열을 원합니다.



4
"none"을 반환하는 대신 undefined를 반환합니다.
JoeyRobichaud

1
나는 그 질문을 보았고 현재 응용 프로그램에 영향을 미치기 때문에 속성을 삭제하고 싶지 않습니다. 개체를 파일에 저장하려고하는데 응용 프로그램에 여전히 라이브 개체가 있으므로 속성을 삭제하면 쓸모 없게됩니다. 또 다른 옵션은 개체를 복제하고 필드를 삭제 한 다음 복제 개체를 문자열 화하는 것입니다.
Nilesh

1
안녕 조, 대단 했어. 정의되지 않은 것이 트릭을 수행했습니다. 감사. 질문을 업데이트하겠습니다
Nilesh

답변:


101

모질라 문서는 반환에게 말한다 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'])));

편집 -혼란을 피하기 위해 하단 기능의 기능 키를 변경했습니다.


34

또 다른 좋은 해결책 : (밑줄 필요)

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

이 방법에 대한 I 투표 내가 그것을 찾을 수 있기 때문에이 .. 더 우아합니다
로미오 시에라

18

Object에서 기본 함수 defineProperty 를 사용할 수 있습니다 .

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

12
이 대답 enumerable은이 속성 설명 자의 값이 거짓 이기 때문에 작동합니다 .
Soul_Master

참고 : 데이터가 배열이고 배열의 n 번째 요소를 숨기려는 경우 작동하지 않습니다.
Alex Szü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

나는 이것이 이미 대답 된 질문이라는 것을 알고 있지만 instatiated 개체를 사용할 때 무언가를 추가하고 싶습니다.

함수를 사용하여 할당하면 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

당신은 또한 instatiated 객체에 있지 않을 때에도 개념을 가지고 놀 수 있습니다.


해당 속성의 값을 설정할 필요가없는 경우에만 작동합니다.
Gabriel C

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

0

ES2017로 쉽게 할 수 있습니다

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

이곳까지 privateProperty1privateProperty2에 할당 exc1하고 exc2그에 따라. 나머지는 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"}


0

다음은 스프레드 연산자 (...)에 대한 나의 접근 방식입니다.

const obj = { name:"hello", age:42, id:"3942" };
const objWithoutId = { ...o, id: undefined }

const jsonWithoutId = JSON.stringify({...o, id:undefined});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.