作为类似 jQuery 生成客户端 web 应用程序更丰富、 功能更强的 JavaScript 框架,我已开始注意到一个问题...

您是怎样在世界上让这组织?

  • 在一个位置放置所有事件处理程序和编写的所有事件的函数?
  • 创建函数/类包装所有功能?
  • 疯狂写,只是希望能制定出最佳?
  • 放弃并获得新的职业生涯?

我提到 jQuery,但一般情况下是任何真正的 JavaScript 代码。我发现,在行后的行开始堆积,变得难以管理的脚本文件或找到您正在查找的内容。很可能是最大的 propblems,我发现有很多方法可以执行相同的操作,很难知道哪一种,是目前普遍认可的最佳做法。

是否有任何一般建议为漂亮和整洁作为您的应用程序的其余部分保持.js文件的最佳方法?或者,这只是一种 IDE?有出有更好的选择吗?


编辑

此问题旨在将代码组织和文件的组织有关的详细信息。已合并文件或拆分内容周围的一些真正很好的示例。

我的问题是︰ 当前普遍接受最佳的练习方式来组织实际代码是什么?您的方法或甚至建议的方法是与网页元素交互,并创建可重用代码并不冲突,彼此是什么?

有些人已列出的命名空间是一个好主意。某些其他方面,更具体地说就是处理页面上的元素并使代码保持井井有条,整齐有哪些?

2008-10-29 15:19:32
问题评论:

人真正花时间来谈代码组织本身,而"不仅仅是"什么样的工具他使用串联和压缩他的 JS 文件︰ stackoverflow.com/questions/16736483/...

回答:

如果 javascript 有命名空间生成,但是找到组织诸如 Dustin 美云介绍,那就太得好多了这里帮助我很多。

var DED = (function() {

    var private_var;

    function private_method()
    {
        // do stuff here
    }

    return {
        method_1 : function()
            {
                // do stuff here
            },
        method_2 : function()
            {
                // do stuff here
            }
    };
})();

将不同的"命名空间",有时个别类放在单独的文件中。通常我开始与一个文件,如类或命名空间获取足够大,以保证它,我将其分隔开到它自己的文件。使用工具来合并所有您生产的文件是一个极好的主意。

我通常是指,随着"crockford 方式"。从我的 + 1

您甚至可以更进一步。看到此链接︰ wait-till-i.com/2007/08/22/...

@MattBriggs 否则调用module pattern,并基于IIFE pattern.

您不需要以某种方式导出的类?从这种模块的外部 does 如何创建一个对象?还是应该有方法createNewSomething()返回的对象中,因此对象创建发生仅在模块内?Hm...我期待 (构造函数) 的类被外界看到。

我尽量避免包括任何 javascript 的 html。所有的代码封装到类,每个类在其自己的文件。对于开发,有单独的 < 脚本 > 标记要包括的每个 js 文件,但它们合并到一个大包的生产,以减少 HTTP 请求的开销。

通常情况下,必须为每个应用程序的单个主 js 文件。因此,如果我正在写的"调查"应用程序,我将有一个名为"survey.js"的 js 文件。此文件将包含到 jQuery 代码的入口点。我在实例化期间创建 jQuery 的引用,然后将它们传递到我对象作为参数。这意味着 javascript 类是纯和不包含任何参考 CSS id 或类名。

// file: survey.js
$(document).ready(function() {
  var jS = $('#surveycontainer');
  var jB = $('#dimscreencontainer');
  var d = new DimScreen({container: jB});
  var s = new Survey({container: jS, DimScreen: d});
  s.show();
});

我还发现命名约定是非常重要的可读性。例如︰ 我在前面添加的 j 到 jQuery 的所有实例。

在上面的示例中,还有名为 DimScreen 的类。(假定这屏幕变暗,并弹出一个警告框)。它需要一个 div 元素,它可以扩大覆盖屏幕,并将一个警告框,因此我在 jQuery 对象中传递。jQuery 有一个插件的概念,但是它看起来限制 (如实例不是永久性的和无法访问) 与任何真实的有利因素。因此,DimScreen 类应恰好使用 jQuery 的标准 javascript 类。

// file: dimscreen.js
function DimScreen(opts) { 
   this.jB = opts.container;
   // ...
}; // need the semi-colon for minimizing!


DimScreen.prototype.draw = function(msg) {
  var me = this;
  me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
  //...
};

我已经建立了一些相当复杂的应用程序,使用此方法。

我发现使用$作为变量名的前缀是更常见的做法,但我可能是错误的。因此, $s = $('...')而不是jS = $('...'),只是我猜的喜好问题。令人感兴趣,因为匈牙利表示法被认为是代码告知。这很离奇方式不同的 JavaScript 代码约定/首一些对我的 C# / Java 编码约定。

它不是代码的 @jamie 在这种情况下,闻它的精确之一少的情况下在匈牙利就是很好您可能想要读取.

@DanAbramov 将感谢您的链接。我真的必须阅读所有的 Joel 的博客,他介绍了事情非常好。的确值得他堂影响/声誉。将涉及Systems Hungarian以及代码告知Apps Hungarian做法为从现在起:)

我猜在 C# 世界,也可能是很好的文章,以促进使用var,既然我想到了它。针对使用var的大多数参数是您不能确定类型返回的内容,但我猜测该参数而不是应该对不知道返回的内容的类。如果使用匈牙利语的应用程序,则不应当让该问题然后...有趣。

@Marnen︰ 我看到您的观点,但其实不是程序员参考意义。前缀 $ 使我想起以后,阅读我的代码时,有助更快地了解。

您可以分解成单独的文件,对于开发,您的脚本,然后创建您一起将它们填塞并在其上运行YUI 压缩机或其他类似的"发布"版本。

有时是不需要的 javascript 脚本。它是一种浪费,发送到客户端的。我认为它的 be 只发送所需的。当然,对于 intranet 应用程序,如长时间,使用 web 应用程序可能更好一些,在第一个页面加载一次,将发送整批。

@DOK 编译应包含 excision 的未使用的资料。

还有的延迟加载尝试并减少带宽需求,其中初始页面加载时,,然后执行异步加载请求的脚本文件 (如其他对此问题的回答中所述) 的概念。不过,这可能需要更多的请求,实际上可能更少可用。@DOK,如果缓存,JS,一个中等的请求可能会比几个小的更好。

做一份Rakefile的早期帖子的灵感来源和供应商目录与WysiHat (通过更改日志提到 RTE) 发布并做一些修改,以包括与JSLintYUI 压缩机与缩小代码检查.

这一想法是使用Sprockets (从 WysiHat) 合并成一个文件的多个 JavaScripts,检查合并文件中具有 JSLint 的语法和 minify 与 YUI 压缩机在分发之前。

系统必备组件

  • Java 运行时
  • ruby 和 rake gem
  • 您应该知道如何放入类路径中的 JAR

现在做

  1. 下载Rhino并放置到您的类路径中的 JAR ("js.jar")
  2. 下载YUI 压缩机并放置到您的类路径中的 JAR (生成/yuicompressor-xyz.jar)
  3. 下载WysiHat和复制"供应商"目录的根的 JavaScript 项目
  4. Rhino 的 JSLint下载并将其放在"供应商"目录

现在创建名为"Rakefile",JavaScript 项目的根目录中的文件并向其中添加以下内容︰

require 'rake'

ROOT            = File.expand_path(File.dirname(__FILE__))
OUTPUT_MERGED   = "final.js"
OUTPUT_MINIFIED = "final.min.js"

task :default => :check

desc "Merges the JavaScript sources."
task :merge do
  require File.join(ROOT, "vendor", "sprockets")

  environment  = Sprockets::Environment.new(".")
  preprocessor = Sprockets::Preprocessor.new(environment)

  %w(main.js).each do |filename|
    pathname = environment.find(filename)
    preprocessor.require(pathname.source_file)
  end

  output = preprocessor.output_file
  File.open(File.join(ROOT, OUTPUT_MERGED), 'w') { |f| f.write(output) }
end

desc "Check the JavaScript source with JSLint."
task :check => [:merge] do
  jslint_path = File.join(ROOT, "vendor", "jslint.js")

  sh 'java', 'org.mozilla.javascript.tools.shell.Main',
    jslint_path, OUTPUT_MERGED
end

desc "Minifies the JavaScript source."
task :minify => [:merge] do
  sh 'java', 'com.yahoo.platform.yui.compressor.Bootstrap', '-v',
    OUTPUT_MERGED, '-o', OUTPUT_MINIFIED
end

如果一切正常,您应该能够在您的控制台中使用以下命令︰

  • rake merge,将不同的 JavaScript 文件合并为一个
  • rake check-检查您的代码 (这是默认的任务,因此您只需键入rake的语法)
  • rake minify -准备缩减版本的 JS 代码

合并源

使用 Sprockets,JavaScript 可以包含预处理器 (或require) 其他 JavaScript 文件。使用以下语法 (名为"main.js",但您可以更改它在 Rakefile) 的初始文件中包含其他脚本︰

(function() {
//= require "subdir/jsfile.js"
//= require "anotherfile.js"

    // some code that depends on included files
    // note that all included files can be in the same private scope
})();

然后...

看看 Rakefile 提供的 WysiHat 设置自动的单元测试了。不错的:) 材料

现在回答

这没有很好地应答的原始问题。我知道,我很抱歉,但我已经在这里发布希望它可能给其他人来组织他们一塌糊涂很有用,因为它。

我解决问题的方法是做尽可能多的面向对象的建模可以,并分隔成不同的文件实现。然后处理程序应尽可能地短。单一实例List的示例也是很好的一个。

和命名空间...还可以深入了解对象结构模仿他们。

if (typeof org === 'undefined') {
    var org = {};
}

if (!org.hasOwnProperty('example')) {
    org.example = {};
}

org.example.AnotherObject = function () {
    // constructor body
};

我不是非常热衷于限制,但此功能很有用,如果您有许多想要移出全局作用域的对象。

代码的组织要求采用约定和文档标准︰
1.Namespace 代码的物理文件;

Exc = {};


2.在这些命名空间 javascript; 组类
3.设置原型或相关的函数或类用于表示实际的对象;

Exc = {};
Exc.ui = {};
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};
Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    ...
};


4.设置以提高代码的约定。例如,将所有内部函数或方法中的对象类型的类属性组合。

Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    this.internal = {
        widthEstimates: function (tips) {
            ...
        }
        formatTips: function () {
            ...
        }
    };
    ...
};


5.请参考文档的命名空间、 类、 方法和变量。必要时,还讨论的某些代码 (某些 FIs 和 Fors,它们通常实现的代码的重要逻辑)。

/**
  * Namespace <i> Example </i> created to group other namespaces of the "Example".  
  */
Exc = {};
/**
  * Namespace <i> ui </i> created with the aim of grouping namespaces user interface.
  */
Exc.ui = {};

/**
  * Class <i> maskdInput </i> used to add an input HTML formatting capabilities and validation of data and information.
  * @ Param {String} mask - mask validation of input data.
  */
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};

/**
  * Class <i> domTips </i> used to add an HTML element the ability to present tips and information about its function or rule input etc..
  * @ Param {String} id - id of the HTML element.
  * @ Param {String} tips - tips on the element that will appear when the mouse is over the element whose identifier is id <i> </i>.
  */
  Exc.ui.domTips = function (id, tips) {
    this.domID = id;
    this.tips = tips;
    ...
};


这些只是一些提示和技巧,但是,非常有助于组织代码。请记住,必须有制度成功 !

请输入您的翻译

Commonly accepted best practices around code organization in JavaScript [closed]

确认取消