Javascript 将图元保存为对象属性是否是一种良好做法?
我正在编写一个小型JavaScript框架,以获得乐趣,并可能实现类似于主干(因此是标记)的实现。我已经开始将元素保存为对象属性,如下所示。我不确定我是否见过这种情况,所以我很好奇这是否会引起任何问题 类似地,如果模块依赖于其他模块,我将以另一个对象的形式列出对象顶部的模块 我想要一种列出依赖项(页面元素或JavaScript模块)并预先检测任何问题的方法。这与依赖注入具有类似(不同)的好处 这是本文中的一个具体问题,它进一步解释了框架是如何工作的Javascript 将图元保存为对象属性是否是一种良好做法?,javascript,backbone.js,Javascript,Backbone.js,我正在编写一个小型JavaScript框架,以获得乐趣,并可能实现类似于主干(因此是标记)的实现。我已经开始将元素保存为对象属性,如下所示。我不确定我是否见过这种情况,所以我很好奇这是否会引起任何问题 类似地,如果模块依赖于其他模块,我将以另一个对象的形式列出对象顶部的模块 我想要一种列出依赖项(页面元素或JavaScript模块)并预先检测任何问题的方法。这与依赖注入具有类似(不同)的好处 这是本文中的一个具体问题,它进一步解释了框架是如何工作的 /*MUserTry ** ** **
/*MUserTry
**
**
**
*/
$A.modelAjax({
Name: 'MUserTry',
S: {
DynSma: SDynSma,
DynTwe: SDynTwe,
DynArc: SDynArc,
AniFlipPage: SAniFlipPage,
ClientStorage: SClientStorage
},
E: {
but: $A('#ut_but')[0]
},
J: {
box: $('#ut_box')
},
init: function () {
var pipe = {},
this_hold = this;
this.J.box.draggable();
this.E.but.addEventListener("click", function () {
pipe = $A.definePipe(this_hold.Name);
$A.ajaxMachine(pipe);
}, false);
},
pre: function (pipe) {
pipe.page.email = this.e_button.getAttribute('data-email');
pipe.proceed = true;
},
post: function (pipe) {
this.S.ClientStorage.setAll(pipe.server.smalls);
this.S.DynSma.run(pipe.server.smalls);
this.S.DynArc.run(pipe.server.arcmarks);
this.S.DynTwe.run(pipe.server.tweets);
this.S.AniFlipPage.run('ma');
},
finish: function (pipe) {
$A.log(pipe);
}
});
好的,首先让我提供一个强制性的警告:“你永远不会得到一个更好的车轮重新发明车轮”。无论您试图完成什么,如果您使用现有的库,几乎可以肯定您将在这方面取得更大的成功。即使有很好的理由让您创建自己的库,至少看看现有的库对您还是有很大的好处 但是。。。也许你只是在享受这个项目的乐趣,而看其他项目并不有趣,所以你没有这么做。很公平 在任何情况下,如果您查看主干,您会发现这种做法是主干视图类的核心。主干中的每个视图都有一个“el”和“$el”属性,它们引用视图的原始DOM元素以及该元素的jQuery包装版本 主干并没有真正的性能问题,因为JS中的变量/属性只是指针;换句话说,当您将一个对象的属性设置为一个元素时,您并不是在复制该元素,而是在添加对该元素的引用(换句话说,这更像是一个标记,而不是一个全新的文档) 不过,一次性主干确实有一个问题(您的框架也会有问题),那就是过时的引用。换句话说,如果您只是从页面中删除元素X,浏览器将停止为其使用内存(最终通过垃圾收集)。但如果有一个对象指向该元素,它将不会被垃圾收集,因为任何带有引用的对象都不是“垃圾” 因此,您必须注意的主要事项是确保这些对象: A) 无论何时删除其元素,或 B) 当它们的元素被删除时,去掉它们的引用(例如,
delete obj.reference
)
如果你不这样做,事情可能仍然会很顺利。。。在您在创建/删除了大量元素的页面上使用它之前,Firefox将开始弹出“此脚本运行时间太长,您真的确定要执行此操作吗?”消息。为什么会导致性能问题?这里的对象是标准变量,使用
SDynSma:SDynSma
和s:{DynSma:SDynSma}
之间没有区别。做一些变量的成本很小:一些变量和一些变量。显然,两种不同的访问方式有不同的成本…但共识似乎认为这是可以忽略的。补充一下,在jQuery源代码中,作者通过执行类似于var doc=window.document的操作,有目的地减少范围查找代码>P.S.对象本身几乎没有性能成本;用物品把东西包装得心满意足。但是物体可以容纳。。。这当然会导致性能问题(特别是如果您认为要删除它,但实际上并不是因为您仍然有对它的引用),它是一个单一的值:someView.el=singleHtmlElement。当您实例化一个视图时,它被设置为初始化过程的一部分,如果您“手动”更改它,您需要调用View.setElement(newElement)让主干知道更改。如果您想了解更多信息,请查看(el定义了几个条目)。您不需要:-)主干视图设计为只包含一个元素。但是,无论你有单元素(el=someElement
),比如主干,还是有多个元素(els=[someElement,someOtherElement]
),我的答案同样适用。:-)就像我说的,通过重新发明轮子来获得乐趣和学习并没有错。我只是说,你可能不会得到一个更好的方向盘(尽管一切都有可能),如果你在一个工作环境中,这肯定不会是对你时间最有效的利用。