2010-03-04 38 views
12

在做了一些关于这个主题的研究之后,我一直在尝试很多模式来组织我的jQuery代码(例如Rebecca Murphy在jQuery Conference上做了一个presentation的例子)。jQuery的代码组织和性能

昨天我检查了(揭示)模块模式。结果看起来有点让人想起YUI语法我想:

//global namespace MyNameSpace 
if(typeof MNS=="undefined"||!MNS){var MNS={};} 

//obfuscate module, just serving as a very simple example 
MNS.obfuscate = function(){ 
    //function to create an email address from obfuscated '@' 
    var email = function(){ 
     $('span.email').each(function(){ 
      var emailAddress = $(this).html().replace(' [ @ ] ','@'); 
      $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>'); 

     }); 
    };  
    return { 
     email: email 
    };  
}(); 

//using the module when the dom's ready 
jQuery(document).ready(function($){ 
    MNS.obfuscate.email(); 
}); 

我到底有几个模块。一些自然包含的“私人成员”,在这种情况下意味着变量和/或函数,这些变量和/或函数对于本模块中的其他函数仅仅是重要的,因此并没有在返回语句中结束。

我认为我的代码连接的部分(与搜索示例有关的所有内容)组合在一个模块中是有意义的,给出了整个事物结构。

但是写这之后,我由约翰(Resig的),在那里他还写了关于模块模式的性能读取article

“实例化功能与一群原型的属性是非常,非常,如果你有一个你想让人们进行交互的经常访问的函数(返回一个对象),那么有利于你拥有对象的属性在原型链中并将其实例化,其代码如下:

// Very fast 
function User(){} 
    User.prototype = { /* Lots of properties ... */ }; 

// Very slow 
function User(){ 
    return { /* Lots of properties */ }; 
} 

(约翰提到他并不反对模块模式“本身” - 只是为了让你知道:)

然后我不知道如果我正在用我的代码进入正确的方向。事情是:我真的不需要任何私人成员,我也不认为我暂时需要继承。 我现在想要的只是一种可读/可维护的模式。我想这可以归结为个人喜好,但我不想结束那些具有(相当严重的)性能问题的可读代码。

我不是JavaScript专家,因此就性能测试而言,更不是专家。首先,我不知道John提到的东西(“经常访问的函数(返回对象),你希望人们与之交互的东西”,很多属性等等)适用于我的代码。我的代码交互的文档不是很大,有100或1000个元素。所以也许这根本不是问题。

但它来到我的脑海里的一件事是,而不是仅仅有

$('span.email').each(function(){ 
    var emailAddress = $(this).html().replace(' [ @ ] ','@'); 
    $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>'); 
}); 

(在domready中函数内部),我创建两个“额外”的功能,模糊和电子邮件,由于使用的模块模式。创建附加功能需要一段时间。问题是:在我的情况下它会是可衡量的吗?

我不确定是否在上面的示例中创建了闭包(在jQuery论坛上的一篇有趣的文章中,我阅读了以下内容:“有一个关于内部函数是否创建闭包的哲学争论, t在外部函数的变量对象上引用任何东西......“),但是我确实在我的真实代码中有闭包。尽管我不认为我在那里有任何循环引用,但我不知道这会导致内存消耗高/垃圾收集问题的程度如何。

我真的很想听听你的意见,也许看到你的代码的一些例子。另外,您更喜欢哪些工具来获取有关执行时间,内存和CPU使用率的信息?

回答

7

我也并不认为我需要继承暂且

确实。这并不适用于将模块用作名称空间。这是关于类实例类似物。

通过使用全新的{name: member}对象中的每个实例创建的对象效率都低于使用new ClassClass.prototype.name= member创建的对象的效率。在原型案例中,member值是共享的,导致重量较轻的实例。

在您的示例中,MNS是单身人士,因此通过原型共享成员没有任何好处。

我不知道,如果在我的例子中创建上面

是封闭,它是。即使在外部函数中未定义变量,仍然会为外部函数创建一个LexicalEnvironment和Scope对象,并绑定thisarguments。一个聪明的JS引擎可能能够优化它,因为每个内部函数都必须隐藏thisarguments以及它们自己的副本,但我不确定任何当前的JS实现是否真的这样做。

在任何情况下,性能差异都应该无法检测到,因为您没有在参数中加入任何重要内容。对于一个简单的模块模式,我不认为有任何伤害。

此外,您更喜欢哪些工具获取有关执行时间,内存和CPU使用率的信息?

开始的地方仅仅是在一个for循环执行代码10000次,看看有多少大new Date().getTime()已经得到了,执行上尽可能多的不同的浏览器多次,你可以弄个。

$(this).html()。replace('[@]','@');

(这是应该做的?目前,它会读取跨度的HTML到一个新的String,用@只更换的[ @ ]第一个实例,并返回一个新String值。它赢得了” t更改DOM中的现有内容。)

+0

谢谢你的回答!我将不得不考虑一下它的主要部分,我想:) 至于电子邮件功能:你当然是对的。我只是想要一个简单的例子,并将其复制到其中。我现在改变了,所以它会更有意义。 – north 2010-03-04 09:19:09

1

您有多少Javascript?根据我的经验,在网页上使用很多的Javascript代码,性能问题一般来自代码,实际上确实是的东西。一般来说,问题来自尝试做太多事情,或试图做一些特别的事情真的很糟糕。一个例子就是尝试像表格行(大表)中的元素那样执行类似绑定处理程序的事情,而不是使用“live”之类的东西。

我的观点是,像你的模块或功能或任何得到组织的东西几乎肯定不会在你的网页上造成任何类型的实际性能问题。什么促使你去解决所有这些麻烦?

+0

感谢你,波蒂。我只是不满意有一堆关于jQuery的准备就绪的函数。我想要一个让阅读和维护代码更容易的模式,对于我自己和其他可能工作的人来说。我对JS编程有一定的了解,了解了jQuery/JS等一系列性能建议,但模式对性能影响有多大的问题要深入一些。所以John Resig的文章让我很好奇。我想我是大多数开发人员:我想进步...... :) – north 2010-03-04 14:36:40

+0

是的,现在**,这使**很有意义。我在我的应用程序中做的是分离所有的JavaScript片段并对它们进行分类(jQuery扩展; blob在“ready”处理程序中运行;等等)。这使维护更容易。为了将它们放在一起,我让我的Ant构建运行Freemarker来组装一个单一的Javascript源代码,然后通过YUICompressor运行。 – Pointy 2010-03-04 14:42:04

+0

哦,到目前为止,它并没有那么多:约250行,包括评论。模块模式会产生一些开销,但是即使没有足够的代码,您也希望以某种方式组织它。我现在将它分成6个模块,这使得它更具可读性。所以在这方面,这种模式适合我。另外,在domready中调用像MNS.obfuscate.email这样的命令,至少可以让你知道发生了什么。 – north 2010-03-04 14:45:07