JavaScript的继承Object.create

问题描述:

好吧,我试图跟踪对Web应用程序的巨大形式所做的任何更改。加载页面时,我创建了一个JS对象,用于“捕获”所有输入字段(选择,单选按钮,复选框等)的初始状态。
当用户改变任何字面值数百个输入元素的值时,新值将在第二个对象中跟踪。当用户单击Update时,将比较这两个对象,并仅发送已更改的值,以相应地更新数据。JavaScript的继承Object.create

而是要建设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(公司政策,黯然)

+1

实例化对象的'prototype'属性* always * undefined。 '__proto__'是[在Firefox中折旧的非标准属性](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/Proto)。你为什么不简单地将一个'change'事件处理程序绑定到输入字段并跟踪更改? – Matt 2012-07-19 10:56:22

+0

这就是我追踪变化的方法,但不是检查'tracker.hasProperty(...)'数百次(记住:200+输入也不例外),我宁愿能够设置新值并将字符串化只有那些已经被修改的 – 2012-07-19 11:29:39

tracker.__proto__ === initialState返回true,而tracker.prototype === initialState评估为假,其实tracker.prototype prope rty未定义。

__proto__ property是非标准且仅限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; 
+0

谢谢,您建议的'deepCreate'方法与我目前使用的方法类似,但仍然需要一个循环。有时候让我感到困惑的是JSON字符串包含各种空洞'{}'。我想使用继承查看作为原始和跟踪器对象都遵循相同的结构,并且有4个深度。正如我目前所做的那样,不使用继承,需要花费太多精力和检查来构建IMO,然后再进行一些比较。我希望能有办法避免所有的体力劳动。哦,我注意到DC的Object.create()是为IE8 – 2012-07-19 12:11:39

+0

定义的,那些空对象需要 - 它们只是说没有属性改变,但它们仍然存在。 – Bergi 2012-07-19 12:19:16

+0

谁是DC?问题不在于是否在IE8中实现* How * Object.create - 它不是本地的。你能打印出这个功能吗? – Bergi 2012-07-19 12:20:12