1

好的,我正在尝试跟踪对 Web 应用程序上的巨大表单所做的任何更改。加载页面时,我创建一个 JS 对象,它“捕获”所有输入字段(选择、单选按钮、复选框等)的初始状态。
当用户改变数百个输入元素中的任何一个的值时新值将在第二个对象中进行跟踪。当用户点击Update时,这两个对象会进行比较,并且只发送那些已更改的值,以相应地更新数据。

我认为使用继承是明智的,而不是构建 2 个完全独立的对象:

var initialState = getInitialState();//eg:{bar:'1',foo:'bar',atom:'bomb',some:{nested:'objects'}}
var tracker = Object.create(initialState);

随着事情的发展,tracker对象可能最终看起来像这样:

{bar:'0',foo:'bar',atom:'peace',some:{nested:'objects'}}

在 FF 和 chrome 中调用JSON.stringify这个对象时,一切都很好:只返回对象自己的属性。在 IE 中不是这样:跟踪器没有prototype属性,所以看起来会Object.create创建副本而不是继承链?
tracker.__proto__ === initialState返回 true,而tracker.prototype === initialState计算结果为 false,实际上该tracker.prototype属性是未定义的。

问题1:是否有另一种方法可以在 IE 中设置继承链,让我剥离未更改的原型值?

问题2:我还想要一种方法——如果可能的话——建立一个允许嵌套对象的继承链。就像现在一样,嵌套对象是通过使用递归函数迭代主对象来处理的。有点傻,因为那是我想省略的。

简而言之:
我想知道这是否存在:

var a = {bar:'1',foo:'bar',atom:'bomb',some:{nested:'objects'}};
var b = Object.magicDeepCreate(a);//<=== preferably X-browser
b.bar = '0';
b.bar.some.nested = 'stuff';
console.log(JSON.stringify(b));
//{"bar":"0","some":{"nested":"stuff"}}

与往常一样:没有 jQuery 标签,意味着没有 jQuery
注意:我所说的 IE 是指怪物 IE8,而不是 IE9(可悲的是公司政策)

4

1 回答 1

2

tracker.__proto__ === initialState返回 true,而tracker.prototype === initialState计算结果为 false,实际上该tracker.prototype属性是未定义的。

__proto__属性是非标准的,仅限 FF。要获取对象的原型对象,请使用Object.getPrototypeOf(). 函数对象prototype属性是引用该函数的所有实例(使用创建的)继承的对象的属性。new

在 IE 中不是这样

Object.create()IE8 完全不支持。您是使用普通垫片还是静默失败?或者你甚至使用了一个真正复制所有属性的函数?

Object.magicDeepCreate(a),最好是X浏览器

这应该很简单,假设所有目标浏览器都实现Object.create

Object.deepCreate = function deepCreate(o) {
    var res = Object.create(o);
    for (var i in o)
        if (Object.hasOwnProperty(o, i) && typeof o[i] == "object")
             res[i] = deepCreate(o[i]);
    return res;
};

仅对已更改的内容进行字符串化

这应该是标准行为JSON.stringify- 原型对象不被考虑在内。

但是,我不确定为什么您需要对该tracker对象进行继承。只需使用一个空对象,并添加所有已更改的属性。如果要删除已重置为初始状态的那些,可以将其存储在一个额外的对象中进行比较 - 但没有继承的理由。只需使用:

Object.emptyStructure = function s(o){
    var res = {};
    for (var i in o)
        if (typeof o[i] == "object")
            res[i] = s(o[i]);
    return res;
};
var initialState = getInitialState();
var tracker = Object.emptyStructure(initialState);

// set:
if (newVal == initialState.some.nested)
    delete tracker.some.nested;
else
    tracker.some.nested = newVal;
于 2012-07-19T11:34:56.993 回答