我正在尝试确定某些javascript的性能影响。在我们的应用程序中,表单包含许多小部件。并非所有窗口小部件都在每个页面上使用,或者窗口小部件可能会被多次使用。我一直在考虑一个类似于以下的模型(请注意,实际的脚本要复杂得多,我将其简化为简短的):
var widget = {
type1: function(args) {
function getName() {
return this._name;
}
return (widget.type1 = function(args) {
return {
_name: args.name,
getName: getName
};
})(args);
}
}
我的想法是,第一次调用widget.type1
函数时,它将初始化widget.type1所需的所有代码。然后,任何后续的widget.type1都将使用这些函数。我知道我可以这样做:
var widget = {
type1: function(args) {
return {
_name: args.name,
getName: function getName() {
return this._name;
}
};
}
}
但是每个type1对象都有它自己的一个函数副本,它会做同样的事情,我认为会使用更多的内存(我已经在o1.getName!= o2.getName的浏览器调试工具中测试过)。
我可以从服务器上写出当前页面上的小部件类型的脚本,但是我不会从缓存单个js文件中获益,而且我不希望将每个小部件放在其中拥有js文件,因为它必须单独下载它们。
这会导致问题吗?是否/应该如我所想的那样表现?其他想法?
修改的
我想我应该解释一下我的理由。我的想法(可能是错误的)是第一次使用窗口小部件时,它会初始化窗口小部件使用的逻辑。例如,如果我从不创建type1小部件,则无需向type1小部件的原型添加一堆函数。我写的代码是高度简化。该小部件可能有500多行代码,我实际上并没有使用getName函数,这只是一个例子。如果未使用窗口小部件,则根本不需要该逻辑。它还将该窗口小部件仅使用的函数保留在全局范围之外。
我目前正在使用对象并向该对象的原型添加函数(例如MyType.prototype.whatever = function(){ ... }
),但我想到如果我从未创建MyType
的对象,为什么还要打扰初始化MyType
的原型?
另一种做我正在思考的方法,这次是使用对象原型(同样,可能有300个函数被添加到type1的原型中。我问的想法是它是否有任何意义根本没有去如果从未创建过type1,则将它们添加到type1的原型中:
var widget = {
_type1Init: function()
{
widget.type1.prototype.getName = function() {
return this._name;
}
widget._type1Init = function(){} //So calling again won't do anything.
},
type1: function(args) {
widget._type1Init();
this._name = args.name;
}
}
if(*someCondition*)
var obj = new widget.type1({ name: "hello world" }); // If an object is created, it gets initilized, otherwise it won't.
答案 0 :(得分:0)
也许你应该考虑:
function type1(argObj){
// use arguments Array for all arguments - you have Object notation
this._name = argObj.name;
// not sure why you need this function
this.getName = function(){
return this._name;
}
}
function widget(){
this.type1 = type1;
}
答案 1 :(得分:0)
我不确定你想要达到什么目标,但我认为这是prototype
的案例
var widget = {
type1: function(args) {
this._name = args.name;
}
};
widget.type1.prototype.getName = function() {
return this._name;
}
var w1 = new widget.type1({ name: 'Alice' });
console.log(w1.getName());
var w2 = new widget.type1({ name: 'Bob' });
console.log(w2.getName());
请参阅JSFiddle
答案 2 :(得分:0)
就个人而言,我认为......不一定是整个重组,但如果你的模块/小部件有:
a)您想要重用的已知“私有静态”功能(实用程序或无状态变换器) b)必须在特定于实例的状态下运行的函数
然后你就进入了IIFE市场。
{
widget_1 : (function () {
var private_static_method = function (a, b, c) {
}; // no access to instance-based, closure state, unless passed as arguments
return function (d, e, f) {
// d, e and f are currently private, instance-based values (closure-scope)
this.public_method = function () { // this is copied per-instance
// has full access to d, e, f
return private_static_function(d, e, f);
};
this.g = d;
};
}())
}
widget_1
是返回的函数。
widget_1
的构造函数现在具有私有静态访问(闭包)到INSIDE包装函数,但是构造函数的OUTSIDE。
所以只有一个副本,但需要注意的是静态函数将 no 视为任何实例的任何私有状态(闭包)。
此外,更进一步确实允许您将JS分解为单个文件(可以安全地构建回一个文件)并让对象在另一侧以完全相同的方式工作。
// core-file.js
var my_widgets = {};
// widget-1.js
(function (core) {
var private_static_method = function () { };
// ...
core.widget_1 = function (d, e, f) { };
}(my_widgets));
然后,您可以重新组合所有文件,并像以前一样访问它们。
var widget_1a = new my_widgets.widget_1(a, b, c);
如果你的绝对没有私有状态,那么你可以在你的IIFE内部做一个构造函数,并为它添加原型(而不是上面的“私有静态”东西)。是“公共静态”,没有访问私有状态。)
widget_1 : (function () {
var Widget_1 = function (d, e, f) { this.g = d; };
Widget_1.prototype.add_one = function () { this.g += 1; };
return Widget_1;
)())
var w1 = new my_widgets.widget_1(x, y, z);
w1.add_one();
w1.g; // == x+1
附带的实用程序功能,封闭的每个实例状态,扩展原型函数等等的组合将允许您执行所需的一切,从降低内存占用(我希望您有数千个这些,然后再担心这个) ,将超级安全(更高内存使用率)对象链接在一起。
注意尽管做疯狂的关闭事情可能是安全的,但客户端代码(或更多 - 特别是世界之间的http(s?)桥梁非常不......
答案 3 :(得分:0)
如果窗口小部件被多次使用,则对象/原型模型将节省内存。
类似的东西:
var wid = {}
wid.objInit=function(p) { this.p=p }
wid.objInit.prototype.doit=function(){ return this.p + ' it'}
wid.init=function(arg){
var w = new wid.objInit(arg)
return w
}
原型编写一次,放入内存一次,每个对象实例都可以调用它。
var w = wid.init('do')
console.log( w.doit() )
var w2 = wid.init('do')
console.log( w2.doit() )