我不确定我是否理解正确的耦合。我被告知,如果我将数据移到外部数据文件(如JSON)中,它会减少整体耦合。 (我同意这一点。)
但是,如果我要创建一个对象来保存JSON所包含的数据,其中的字段直接映射到JSON的结构,那还不会在对象和JSON之间创建紧密耦合的链接吗?
例如:
"images": [{
"source" : "images/foo.png",
"size" : "thumbnail",
"alt" : "Foo"
},
{
"source" : "images/bar.png",
"size" : "thumbnail",
"alt" : "bar"
}]
然后我们有一些对象,应用程序模型的一部分:
function FooBarImage (jsonObj) {
this.source = jsonObj.source;
this.size = jsonObj.size;
this.alt = jsonObj.alt;
}
FooBarImage.prototype.doStuff = function () { ... }
这里,FooBarImage
对象知道JSON对象的内部格式。如果要更改JSON数据的格式(例如,我们要添加新字段,或重命名现有字段),我们是否还必须对构造函数进行更改?
我是否误解了某些内容,还是有其他方法可以进一步解耦代码和数据?
答案 0 :(得分:0)
您可以轻松地反映" /"地图"你的jsonObject(由提供的JSON字符串反序列化产生的文字对象)。您可以遍历对象属性并将它们分配给您的实例:
function FooBarImage (jsonObj) {
Object.keys(jsonObj).forEach(function(prop) {
this[prop] = jsonObj[prop];
}
}
FooBarImage.prototype.doStuff = function () { ... }
样品:
function dirtyMap(fromObj, toObj) {
Object.keys(fromObj).forEach(function(prop) {
toObj[prop] = fromObj[prop];
});
return toObj; // chain me?
};
function FooBarImage (jsonObj) {
dirtyMap(jsonObj, this);
};
FooBarImage.prototype.doStuff = function () {
console.log(this);
};
var json = `[{
"source" : "images/foo.png",
"size" : "thumbnail",
"alt" : "Foo"
},
{
"source" : "images/bar.png",
"size" : "thumbnail",
"alt" : "bar"
}]`
, images = JSON.parse(json)
, instances = images.map(function(img) { return new FooBarImage(img); })
;
instances.forEach(function(instance) { instance.doStuff(); });

另一种解决方案(当然还有其他解决方案)是使用工厂:
var createFooBarImage = function createFooBarImage(img) {
var fooBarImage = Object.create(img);
fooBarImage.doStuff = function () {
console.log(this);
};
return fooBarImage;
}
样品:
var json = `[{
"source" : "images/foo.png",
"size" : "thumbnail",
"alt" : "Foo"
},
{
"source" : "images/bar.png",
"size" : "thumbnail",
"alt" : "bar"
}]`
, createFooBarImage = function createFooBarImage(img) {
var fooBarImage = Object.create(img);
fooBarImage.doStuff = function () {
console.log(this);
};
return fooBarImage;
}
, images = JSON.parse(json)
, instances = images.map(function(img) { return createFooBarImage(img); })
;
instances.forEach(function(instance) { instance.doStuff(); });