Ẩn các giá trị nhất định trong đầu ra từ JSON.stringify ()


86

Có thể loại trừ các trường nhất định được đưa vào chuỗi json không?

Đây là một số mã giả

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

Tôi muốn loại trừ privateProperty1 và privateproperty2 xuất hiện trong chuỗi json

Vì vậy, tôi nghĩ, tôi có thể sử dụng hàm thay thế stringify

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

và trong chuỗi ký tự

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

Nhưng trong jsonString, tôi vẫn thấy nó là

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

Tôi muốn chuỗi không có privateproperties trong chúng.



4
thay vì trả về "không" trả về không xác định.
JoeyRobichaud

1
Tôi đã thấy câu hỏi đó và tôi không muốn xóa thuộc tính vì nó ảnh hưởng đến ứng dụng hiện tại của tôi. Tôi đang cố gắng lưu đối tượng vào một tệp và ứng dụng vẫn có đối tượng trực tiếp nên việc xóa thuộc tính sẽ khiến nó trở nên vô dụng. Một tùy chọn khác là tôi có thể sao chép đối tượng, xóa các trường và sau đó xâu chuỗi đối tượng nhân bản.
Nilesh

1
Này Joe, điều đó thật tuyệt. Không xác định đã lừa. Cảm ơn. Tôi sẽ cập nhật câu hỏi
Nilesh

Câu trả lời:


100

Tài liệu Mozilla cho biết hãy quay lại undefined(thay vì "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));

Đây là một phương pháp nhân bản, trong trường hợp bạn quyết định đi theo con đường đó (theo nhận xét của bạn).

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

CHỈNH SỬA - Tôi đã thay đổi phím chức năng ở chức năng dưới cùng để tránh gây nhầm lẫn.


33

Một giải pháp tốt khác: (yêu cầu gạch dưới)

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

Lợi ích của giải pháp này là bất kỳ ai gọi JSON.stringify trên x sẽ có kết quả chính xác - bạn không phải thay đổi các lệnh gọi JSON.stringify riêng lẻ.

Phiên bản không gạch dưới:

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

Tôi bỏ phiếu cho phương pháp này bởi vì tôi thấy nó là tao nhã hơn ..
Romeo Sierra

18

Bạn có thể sử dụng hàm gốc defineProperty từ Object:

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

12
Câu trả lời này hoạt động vì enumerablegiá trị của bộ mô tả thuộc tính này là sai.
Soul_Master

Lưu ý: Nó không hoạt động nếu dữ liệu là một mảng và người ta muốn ẩn phần tử thứ n của nó.
Alex Szücs

3

Cách dễ dàng hơn để làm.

  1. Tạo một biến và gán một mảng trống. Điều này làm cho đối tượng trở thành nguyên mẫu của mảng.
  2. Thêm các phím không phải số trên đối tượng này.
  3. Tuần tự hóa đối tượng này bằng JSON.stringify
  4. Bạn sẽ thấy rằng không có gì được tuần tự hóa từ đối tượng này.

~~~

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 là một giải pháp khác gần với giải pháp defineProperty (các thuộc tính được định nghĩa theo cách tương tự) nhưng theo cách này, bạn xác định các thuộc tính để hiển thị ngay từ đầu. Bằng cách này, bạn chỉ có thể hiển thị các thuộc tính mà bạn muốn bằng cách đặt enumerablegiá trị thuộc tính thành true (false theo mặc định), JSON.stringify đang bỏ qua các thuộc tính không thể liệt kê, nhược điểm là thuộc tính này cũng sẽ bị ẩn khi sử dụng for-in vòng lặp trên đối tượng hoặc các chức năng như 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

Lưu ý cho câu trả lời của Miroslaw Dylag : Thuộc tính được xác định phải là tài sản riêng của nó. Nếu không nó sẽ thất bại.

Không hoạt động:

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)

Làm:

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

Tôi biết đây đã là một câu hỏi đã được trả lời, nhưng tôi muốn thêm điều gì đó khi sử dụng các đối tượng được cài đặt sẵn.

Nếu bạn gán nó bằng một hàm, nó sẽ không được đưa vào kết quả JSON.stringify ().

Để truy cập giá trị, hãy gọi nó dưới dạng một hàm, kết thúc bằng ()

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

Bạn cũng có thể chơi với khái niệm này ngay cả khi không ở trên các đối tượng đã cài đặt sẵn.


Điều này chỉ hoạt động nếu bạn không cần đặt giá trị của thuộc tính đó.
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

bạn có thể làm điều đó dễ dàng với ES2017

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

Ở đây privateProperty1privateProperty2được chỉ định cho exc1exc2phù hợp. Phần còn lại được gán cho foobiến mới tạo



0

Đây là một cách tiếp cận khác, mặc dù không hỗ trợ Internet Explorer.

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

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

0

Đây là một câu hỏi cũ, nhưng tôi đang thêm một câu trả lời vì có một cách đơn giản hơn nhiều để giải quyết vấn đề này. Chuyển một mảng chuỗi mà bạn muốn xuất trong 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"}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.