JavaScript inheritance Object.create

JavaScript inheritance Object.create

本文关键字:create Object inheritance JavaScript      更新时间:2023-12-17

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

与其构建两个完全独立的对象,我认为使用继承是明智的:

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:如果可能的话,我还想要一个方法来建立一个允许嵌套对象的继承链。现在,嵌套对象是通过使用递归函数迭代main对象来处理的。有点傻,因为这正是我想要省略的。

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

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(遗憾的是,公司政策)

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

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

IE 中并非如此

在IE8中根本不支持Object.create()。你是使用了通用垫片还是它无声地失败了?或者你甚至使用了一个真正复制所有属性的函数?

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;