将JSONstringparsing为JavaScript中的特定对象原型

我知道如何parsing一个JSONstring,并把它变成一个JavaScript对象。 您可以在现代浏览器(和IE9 +)中使用JSON.parse() )。

这很好,但是我怎样才能把这个JavaScript对象变成一个特定的 JavaScript对象(即用一个特定的原型)呢?

例如,假设你有:

 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 

再次,我不想知道如何将JSONstring转换为通用的JavaScript对象。 我想知道如何将JSONstring转换为“Foo”对象。 也就是说,我的对象现在应该有一个函数“testing”和属性“a”和“b”。

更新在做了一些研究之后,我想到了这个…

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

这会工作吗?

更新2017年5月 :这样做的“现代”方式是通过Object.assign ,但在IE 11或更旧版本的Android浏览器中不提供此function。

目前的答案包含了很多手卷或库代码。 这不是必须的。

  1. 使用JSON.parse('{"a":1}')来创build一个普通的对象。

  2. 使用其中一个标准化function来设置原型:

    • Object.assign(new Foo, { a: 1 })
    • Object.setPrototypeOf({ a: 1 }, Foo.prototype)

看下面的例子(这个例子使用本地的JSON对象)。 我的变化在大写:

 function Foo(obj) // CONSTRUCTOR CAN BE OVERLOADED WITH AN OBJECT { this.a = 3; this.b = 2; this.test = function() {return this.a*this.b;}; // IF AN OBJECT WAS PASSED THEN INITIALISE PROPERTIES FROM THAT OBJECT for (var prop in obj) this[prop] = obj[prop]; } var fooObj = new Foo(); alert(fooObj.test() ); //Prints 6 // INITIALISE A NEW FOO AND PASS THE PARSED JSON OBJECT TO IT var fooJSON = new Foo(JSON.parse('{"a":4,"b":3}')); alert(fooJSON.test() ); //Prints 12 

你想添加JSON序列化/反序列化function吗? 然后看看这个:

你想达到这个目的:

UML

toJson()是一个正常的方法。
fromJson()是一个静态方法。

实现

 var Book = function (title, author, isbn, price, stock){ this.title = title; this.author = author; this.isbn = isbn; this.price = price; this.stock = stock; this.toJson = function (){ return ("{" + "\"title\":\"" + this.title + "\"," + "\"author\":\"" + this.author + "\"," + "\"isbn\":\"" + this.isbn + "\"," + "\"price\":" + this.price + "," + "\"stock\":" + this.stock + "}"); }; }; Book.fromJson = function (json){ var obj = JSON.parse (json); return new Book (obj.title, obj.author, obj.isbn, obj.price, obj.stock); }; 

用法

 var book = new Book ("t", "a", "i", 10, 10); var json = book.toJson (); alert (json); //prints: {"title":"t","author":"a","isbn":"i","price":10,"stock":10} var book = Book.fromJson (json); alert (book.title); //prints: t 

注意:如果你想要的话,你可以通过var titlevar author等方式来更改所有的属性定义,比如this.titlethis.author等等,并添加getters来完成UML定义。

我觉得有用的博客文章: 了解JavaScript原型

你可以混淆对象的__proto__属性。

 var fooJSON = jQuery.parseJSON({"a":4, "b": 3}); fooJSON.__proto__ = Foo.prototype; 

这允许fooJSONinheritanceFoo原型。

我不认为这在IE中可行,但至less从我读过的内容来看。

为了完整起见,下面是一个简单的单线程(我不需要检查非Foo属性):

 var Foo = function(){ this.bar = 1; }; // angular version var foo = angular.extend(new Foo(), angular.fromJson('{ "bar" : 2 }')); // jquery version var foo = jQuery.extend(new Foo(), jQuery.parseJSON('{ "bar" : 3 }')); 

另一种方法是使用Object.create 。 作为第一个参数,你传递原型,第二个parameter passing一个属性映射到描述符:

 function SomeConstructor() { }; SomeConstructor.prototype = { doStuff: function() { console.log("Some stuff"); } }; var jsonText = '{ "text": "hello wrold" }'; var deserialized = JSON.parse(jsonText); // This will build a property to descriptor map // required for #2 argument of Object.create var descriptors = Object.keys(deserialized) .reduce(function(result, property) { result[property] = Object.getOwnPropertyDescriptor(deserialized, property); }, {}); var obj = Object.create(SomeConstructor.prototype, descriptors); 

而这在技术上并不是你想要的,如果你事先知道你想要处理的对象的types,你可以使用已知对象的原型的调用/应用方法。

你可以改变这一点

 alert(fooJSON.test() ); //Prints 12 

对此

 alert(Foo.prototype.test.call(fooJSON); //Prints 12 

我在这个问题中错过了什么,或者为什么没有人提到自2011年以来JSON.parse reviver参数?

下面是解决scheme的简单代码: https : //jsfiddle.net/Ldr2utrr/

 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}`, function(key,value){ if(key!=="") return value; //logic of course should be more complex for handling nested objects etc. let res = new Foo(); res.a = value.a; res.b = value.b; return res; }); // Here you already get Foo object back alert(fooJSON.test() ); //Prints 12 

PS:你的问题令人困惑:>> 这很好,但是我怎样才能把这个JavaScript对象变成一个特定的JavaScript对象(即用一个特定的原型)呢? 与标题相矛盾,你在哪里询问JSONparsing,但引用的段落问询关于JS运行时对象原型replace。

Olivers的答案是非常明确的,但是如果你正在寻找一个angular度js的解决scheme,我已经写了一个很好的模块叫做Angular-jsClass,这样做很容易,当你瞄准一个大项目时,用单数表示定义的对象总是很糟糕但是说开发人员面临的问题正是BMiner所说的,如何序列化一个json到原型或构造符号对象

 var jone = new Student(); jone.populate(jsonString); // populate Student class with Json string console.log(jone.getName()); // Student Object is ready to use 

https://github.com/imalhasaranga/Angular-JSClass