ซ่อนค่าบางอย่างในเอาต์พุตจาก JSON.stringify ()


87

เป็นไปได้ไหมที่จะยกเว้นบางฟิลด์ไม่ให้รวมอยู่ในสตริง json

นี่คือรหัสหลอก

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

ฉันต้องการแยก privateProperty1 และ privateproperty2 ไม่ให้ปรากฏในสตริง json

ดังนั้นฉันคิดว่าฉันสามารถใช้ฟังก์ชันตัวเปลี่ยนสตริงได้

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 }

ฉันต้องการสตริงที่ไม่มีคุณสมบัติส่วนตัวอยู่ในนั้น


อาจซ้ำกันได้: stackoverflow.com/questions/208105/…
Jared Farrish

4
แทนที่จะส่งคืน "ไม่มี" กลับไม่ได้กำหนด
JoeyRobichaud

1
ฉันเห็นคำถามนั้นและไม่ต้องการลบคุณสมบัติเนื่องจากมีผลต่อแอปพลิเคชันปัจจุบันของฉัน ฉันพยายามบันทึกวัตถุลงในไฟล์และแอปพลิเคชันยังคงมีออบเจ็กต์อยู่ดังนั้นการลบคุณสมบัติจะทำให้ไร้ประโยชน์ อีกทางเลือกหนึ่งคือฉันสามารถโคลนวัตถุลบฟิลด์แล้วสตริงวัตถุโคลน
Nilesh

1
เฮ้โจเยี่ยมมาก เคล็ดลับที่ไม่ได้กำหนดทำ ขอบคุณ. ฉันจะอัปเดตคำถาม
Nilesh

คำตอบ:


102

เอกสาร 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'])));

แก้ไข - ฉันเปลี่ยนปุ่มฟังก์ชันในฟังก์ชันด้านล่างเพื่อป้องกันไม่ให้สับสน


34

อีกวิธีที่ดี: (ต้องมีเครื่องหมายขีดล่าง)

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

ข้อดีของโซลูชันนี้คือทุกคนที่เรียก JSON.stringify บน x จะได้ผลลัพธ์ที่ถูกต้อง - คุณไม่จำเป็นต้องแก้ไขการโทร JSON.stringify ทีละรายการ

รุ่นที่ไม่ขีดล่าง:

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

ฉันโหวตให้แนวทางนี้เพราะฉันคิดว่ามันดูหรูหรากว่า ..
Romeo Sierra

18

คุณสามารถใช้ฟังก์ชัน native definePropertyจาก Object:

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เป็นจริง (เท็จโดยค่าเริ่มต้น) 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

คุณยังสามารถเล่นกับแนวคิดได้แม้ว่าจะไม่ได้อยู่บนวัตถุที่ติดตั้ง


วิธีนี้ใช้ได้เฉพาะในกรณีที่คุณไม่จำเป็นต้องตั้งค่าของคุณสมบัตินั้น
Gabriel C

1

นี่เป็นคำถามเก่า แต่ฉันกำลังเพิ่มคำตอบเนื่องจากมีวิธีจัดการที่ง่ายกว่านี้มาก ส่งอาร์เรย์ของสตริงที่คุณต้องการส่งออกใน 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
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'
}

ที่นี่privateProperty1และprivateProperty2ได้รับมอบหมายให้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

นี่คือแนวทางของฉันกับตัวดำเนินการสเปรด (... ):

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

const jsonWithoutId = JSON.stringify({...o, id:undefined});

0

ฉันสมัครรับหัวข้อของ 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(""));
        }
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.