Saya tahu cara mengurai String JSON dan mengubahnya menjadi Obyek JavaScript. Anda dapat menggunakan JSON.parse()
di browser modern (dan IE9 +).
Itu hebat, tetapi bagaimana saya bisa mengambil Objek JavaScript itu dan mengubahnya menjadi Objek JavaScript tertentu (yaitu dengan prototipe tertentu)?
Misalnya, anggap Anda memiliki:
function Foo()
{
this.a = 3;
this.b = 2;
this.test = function() {return this.a*this.b;};
}
var fooObj = new Foo();
alert(fooObj.test() ); //Prints 6
var fooJSON = JSON.parse({"a":4, "b": 3});
//Something to convert fooJSON into a Foo Object
//....... (this is what I am missing)
alert(fooJSON.test() ); //Prints 12
Sekali lagi, saya tidak bertanya-tanya bagaimana cara mengubah string JSON menjadi Obyek JavaScript umum. Saya ingin tahu cara mengubah string JSON menjadi Obyek "Foo". Artinya, Objek saya sekarang harus memiliki fungsi 'tes' dan properti 'a' dan 'b'.
PEMBARUAN Setelah melakukan riset, saya memikirkan hal ini ...
Object.cast = function cast(rawObj, constructor)
{
var obj = new constructor();
for(var i in rawObj)
obj[i] = rawObj[i];
return obj;
}
var fooJSON = Object.cast({"a":4, "b": 3}, Foo);
Apakah itu akan berhasil?
UPDATE Mei, 2017 : Cara "modern" untuk melakukan ini, adalah melalui Object.assign
, tetapi fungsi ini tidak tersedia di IE 11 atau lebih lama browser Android.
Jawaban:
Jawaban saat ini berisi banyak linting tangan atau kode perpustakaan. Ini tidak perlu.
Gunakan
JSON.parse('{"a":1}')
untuk membuat objek polos.Gunakan salah satu fungsi standar untuk mengatur prototipe:
Object.assign(new Foo, { a: 1 })
Object.setPrototypeOf({ a: 1 }, Foo.prototype)
sumber
Object.setPrototypeOf(...)
. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…setPrototypeOf
adalah deskriptor properti.Lihat contoh di bawah ini (contoh ini menggunakan objek JSON asli). Perubahan saya dikomentari dalam MODAL:
sumber
for (var prop in obj) {if (obj.hasOwnProperty(prop)) {this[prop] = obj[prop];}}
for (var prop in obj) {if (this.hasOwnProperty(prop)) {this[prop] = obj[prop];}}
. Ini mengasumsikan Anda mengharapkan server untuk mengisi semua properti, IMO juga harus membuang jika obj.hasOwnProperty () gagal ...Apakah Anda ingin menambahkan fungsionalitas serialisasi / deserialisasi JSON, bukan? Kemudian lihat ini:
Anda ingin mencapai ini:
toJson () adalah metode normal.
fromJson () adalah metode statis.
Implementasi :
Penggunaan :
Catatan: Jika Anda ingin Anda dapat mengubah semua definisi properti seperti
this.title
,this.author
, dll denganvar title
,var author
, dll dan menambahkan getter kepada mereka untuk mencapai definisi UML.sumber
toJson()
metode Anda - terlepas dari apakah itu memiliki properti individual yang di-hardcode atau menggunakan masing-masing - perlu menambahkan kode escape backslash untuk beberapa karakter yang bisa berada di setiap properti string. (Judul buku mungkin memiliki tanda kutip, misalnya.)JSON.stringify()
alih-alih menulis ke JSon () sendiri. Tidak perlu menemukan kembali roda sekarang karena semua browser modern mendukungnya.serializable = ['title', 'author', ...]
.JSON.stringify(serializable.reduce((obj, prop) => {...obj, [prop]: this[prop]}, {}))
Posting blog yang menurut saya berguna: Memahami Prototipe JavaScript
Anda dapat mengacaukan properti __proto__ dari Object.
Ini memungkinkan fooJSON untuk mewarisi prototipe Foo.
Saya tidak berpikir ini bekerja di IE, meskipun ... setidaknya dari apa yang saya baca.
sumber
__proto__
sudah lama ditinggalkan . Selain itu, untuk alasan kinerja, tidak disarankan untuk memodifikasi properti internal [[Prototipe]] dari objek yang sudah dibuat (dengan mengatur__proto__
atau dengan cara lain).[[prototype]]
dan tampaknya tidak relevan di Chrome. Dalam firefox, panggilan baru lebih lambat daripada menggunakan prototipe, dan Object.create lebih cepat. Saya kira masalah dengan FF adalah bahwa tes pertama lebih lambat dari yang terakhir, hanya masalah eksekusi saja. Di chrome semuanya berjalan dengan kecepatan yang hampir sama. Maksud saya akses properti dan penempatan metode. Creatin lebih cepat dengan yang baru, tetapi itu tidak begitu penting. lihat: jsperf.com/prototype-change-test-8874874/1 dan: jsperf.com/prototype-changed-method-callObject.setPrototypeOf(fooJSON, Foo.prototype)
bukannya menetapkanfooJSON.__proto__
... kan?Apakah saya melewatkan sesuatu dalam pertanyaan atau mengapa tidak ada yang menyebutkan
reviver
parameterJSON.parse
sejak 2011?Berikut adalah kode sederhana untuk solusi yang berfungsi: https://jsfiddle.net/Ldr2utrr/
PS: Pertanyaan Anda membingungkan: >> Itu bagus, tapi bagaimana saya bisa mengambil Objek JavaScript itu dan mengubahnya menjadi Obyek JavaScript tertentu (yaitu dengan prototipe tertentu)? bertentangan dengan judul, di mana Anda bertanya tentang parsing JSON, tetapi paragraf yang dikutip menanyakan tentang penggantian prototipe objek runtime JS.
sumber
Pendekatan alternatif bisa digunakan
Object.create
. Sebagai argumen pertama, Anda meneruskan prototipe, dan untuk argumen kedua Anda meneruskan peta nama properti ke deskriptor:sumber
Saya suka menambahkan argumen opsional ke konstruktor dan panggilan
Object.assign(this, obj)
, lalu menangani properti apa pun yang merupakan objek atau array objek itu sendiri:sumber
Demi kelengkapan, berikut ini adalah satu-liner sederhana yang saya dapatkan (saya tidak perlu memeriksa properti non-Foo):
sumber
Saya membuat paket yang disebut json-dry . Ini mendukung referensi (melingkar) dan juga instance kelas.
Anda harus mendefinisikan 2 metode baru di kelas Anda (
toDry
pada prototipe danunDry
sebagai metode statis), daftarkan kelas (Dry.registerClass
), dan pergilah.sumber
Sementara, ini bukan apa yang Anda inginkan secara teknis, jika Anda tahu sebelumnya jenis objek yang ingin Anda tangani, Anda dapat menggunakan metode panggilan / terapkan dari prototipe objek yang diketahui.
Anda bisa mengubahnya
untuk ini
sumber
Saya telah menggabungkan solusi yang saya dapat menemukan dan mengkompilasinya menjadi generik yang secara otomatis dapat mem-parsing objek kustom dan semua bidang itu secara rekursif sehingga Anda dapat menggunakan metode prototipe setelah deserialization.
Salah satu anggapan adalah bahwa Anda mendefinisikan suatu arsip khusus yang menunjukkan jenisnya di setiap objek yang ingin Anda terapkan jenisnya secara otomatis (
this.__type
dalam contoh).pemakaian:
Jenis fungsi penugasan (ini bekerja secara rekursif untuk menetapkan jenis ke objek bersarang; ia juga beralih melalui array untuk menemukan objek yang cocok):
sumber
Jawaban yang diterima saat ini tidak berfungsi untuk saya. Anda harus menggunakan Object.assign () dengan benar:
Anda membuat objek dari kelas ini secara normal:
Jika Anda memiliki string json yang perlu Anda parsing ke dalam kelas Person, lakukan seperti ini:
sumber
Jawaban Olivers sangat jelas, tetapi jika Anda mencari solusi dalam js angular, saya telah menulis modul yang bagus yang disebut Angular-jsClass yang memudahkan ini, memiliki objek yang didefinisikan dalam notasi litaral selalu buruk ketika Anda bertujuan untuk proyek besar tetapi mengatakan bahwa pengembang menghadapi masalah yang persis kata BMiner, bagaimana membuat serial json ke prototipe atau objek notasi konstruktor
https://github.com/imalhasaranga/Angular-JSClass
sumber