需要时创建javascript函数

时间:2014-01-14 00:12:45

标签: javascript performance

我正在尝试确定某些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.

4 个答案:

答案 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() )