我想在这个问题上添加一个答案,因为我最近一直在浏览一些好,坏但主要是丑陋的Java,并且我对Java和Java开发人员与JS和JS开发人员实际上可能基于某种类似于有用事实的东西。
有IDE,但有助于理解为什么没有很多
我一直在尝试Webstorm,因为我发现自己被Node开发所吸引,虽然我实际上购买了它还算不错,但是我仍然倾向于在Scite中比WS打开js文件更多。这样做的原因是,您可以用更少的钱在JS上做更多的事,而且还因为UI工作可以立即得到反馈,因此浏览器开发工具(尤其是Chrome浏览器和Firebug)实际上非常出色,并且(考虑了非浏览器的上下文) )无需重新编译即可快速轻松地运行更改后的代码。
我相当确信的另一件事是,IDE通过启用您实际上用JavaScript买不起的草率代码来基本上创建自己的需求。是否想了解我们如何在JS中进行管理?首先尝试在没有IDE的情况下尝试用Java写一些不平凡的东西,并密切注意您必须开始思考的事情,这样才能在不移动IDE的情况下真正维护/修改代码,这可能会有所帮助。向前。IMO,无论是否具有IDE,同样的事情对于编写可维护的代码仍然至关重要。如果我必须编写一个为期四年的编程课程,那么为了避免工具和依赖关系发生扭曲,它不会让您在头两年接触IDE。
结构体
经验丰富的JS开发人员可以处理复杂的应用程序,并且可以构造代码。实际上,由于缺乏IDE来为我们阅读代码的早期历史,我们往往不得不擅长做一件事,而且还因为强大的表达语言可以快速地完全表达无法维护的灾难代码库,如果您不认真思考的话。
实际上,最近在了解我们的Java代码库时,我的学习曲线相当陡峭,直到我最终意识到这都不是正确的OOP。类不过是一堆松散相关的方法,它们改变了位于bean或DTO或静态getter / setter中的全局可用数据。基本上,这就是OOP应该取代的那只老野兽。因此,我基本上不再考虑代码。我刚刚学习了快捷键,并在混乱中进行了追踪,一切都变得更加顺利。因此,如果您尚未养成这种习惯,请对OOD进行更多的思考。
一个结构良好的JS应用程序在最高级别上将倾向于由复杂的功能(例如jQuery)和彼此交互的对象组成。我会说,以任何语言编写的结构良好,易于维护的应用程序的标志是,无论您是使用IDE还是Notepad ++进行查看,它都非常清晰易读。这是我高度依赖依赖注入和将测试优先TDD发挥到极致的主要原因之一。
最后,放手上课。学习原型继承。实际上,当您确实需要继承时,它很容易实现。我发现合成方法在JS中往往会更好地工作,而且,当我看到任何一种语言都在继承一个或两个以上级别的继承时,我个人就会开始生病并遭受EXTJS夜惊。
核心原则优先
我正在谈论所有其他良好实践应从中获得的核心内容:DRY,YAGNI,最少惊讶的原则,问题域的清晰分隔,编写接口以及编写易于阅读的代码是我的个人核心。提倡放弃这些做法的任何更复杂的事情,都应视为任何语言的Kool Aid,尤其是像JavaScript这样的语言,在其中很容易为下一个家伙留下非常混乱的代码的遗产。例如,松散耦合是好东西,直到您深入到为止,您甚至无法分辨对象之间的交互发生在哪里。
不要害怕动态打字
JavaScript中没有很多核心类型。在大多数情况下,动态转换规则是实用且直截了当的,但是学习它们很有意义,因此您可以更好地学习管理数据流,而无需不必要的转换和毫无意义的验证例程。相信我。严格类型对于提高性能和发现编译问题非常有用,但是它们不能保护您免受任何侵害。
了解JS函数和闭包的知识
可以说,JS的一流功能是JS赢得“唯一值得与客户端网络联系并获得大奖的语言”的主要原因。是的,实际上存在竞争。它们也是JS的主要功能。我们用它们构造对象。一切都取决于功能。而且它们具有方便的功能。我们可以通过arguments关键字检查参数。我们可以在作为其他对象的方法的上下文中临时附加并触发它们。而且,它们使事件驱动的方法易于实施。简而言之,他们使JS成为降低源代码的复杂性并适应JS本身(但主要是DOM API)的各种实现的绝对野兽。
在采用之前重新评估模式/实践
一流的函数和动态类型使许多更复杂的设计模式在JS中变得毫无意义且繁琐。但是,鉴于JS具有高度的灵活性,其中一些简单的模式非常有用且易于实现。适配器和装饰器特别有用,我发现单例对于复杂的ui小部件工厂很有用,这些工厂还充当其所构建ui元素的事件管理器。
遵循语言的领导,事半功倍
我相信其中一名Java主管会提出这样的论点,即冗长实际上是一个积极的功能,可使各方更容易理解代码。g。如果这是真的,那么法律术语将更易于阅读。只有作家才能使他们所写的内容更容易理解,而您只能通过偶尔使自己陷入另一个人的脚步来做到这一点。因此,请接受这两个规则。1.尽可能直接和清晰。2.已经到了该死的地步。这样做的好处是,干净,简洁的代码比必须遍历二十五个层才能从触发器到实际所需的操作要容易理解和维护几个数量级。实际上,大多数提倡使用更严格语言的东西的模式都是针对JavaScript没有限制的变通办法。
一切都是可锻的,没关系
JS可能是最受欢迎的保护主义语言之一。拥抱。它工作正常。例如,您可以通过在构造函数中声明常规变量来编写具有不可访问的持久性“私有”变量的对象,而我经常这样做。但这并不是要保护我的代码或代码用户不受其侵害(他们可以在运行时将其替换为自己的版本)。而是要发出意图,因为这样的假设是,另一个人足够胜任,不想破坏任何依赖关系,并且会看到您并不想直接解决它,也许是有充分的理由。
没有大小限制,只有问题域
我所见过的所有Java代码库最大的问题是类文件过多。首先,SOLID只是您应该已经了解的有关OOP的令人困惑的重复。一个班级应处理一组特定的相关问题。一种方法不是一个问题。仅通过添加所有无用的类语法来引导,就可以使用糟糕的旧链接func-spaghetti C代码。没有大小或方法限制。如果有必要在已经很长的函数,类或构造函数中添加某些内容,则是有道理的。以jQuery为例。它是单个函数中的整个库长工具集,这没有任何问题。我们是否仍然需要jQuery取决于合理的争论,但就设计而言,
如果您只知道Java,请尝试使用不基于C的语法
当我由于喜欢听到有关Django的知识而开始迷惑Python时,我学会了将语法与语言设计区分开来。结果,将Java和C作为它们的语言设计部分的总和而不是它们使用相同语法所做的不同事情的总和来理解变得更加容易。一个不错的副作用是,您在设计方面对其他语言的了解越多,您就可以通过对比更好地了解自己最了解的一种语言的优势/劣势。
结论
现在,考虑所有这些,让我们解决您的所有问题点:
- 没有立即找到函数入口点的方法(纯文本搜索除外,纯文本搜索可能会导致随后在调用层次结构之后进一步搜索方法,而其中两到三个您忘记了从哪里开始)
Chrome和Firebug实际上确实具有呼叫跟踪功能。但也请参阅我在结构和保持简洁明了方面的观点。您越会认为应用程序是相互封装的,构造良好的大型结构,就越容易弄清问题出在哪里是谁的错。我会说Java也是如此。我们有类似类的函数构造函数,可以完美地解决传统的OOP问题。
function ObjectConstructor(){
//No need for an init method.
//Just pass in params and do stuff inside for instantiation behavior
var privateAndPersistent = true;
//I like to take advantage of function hoisting for a nice concise interface listing
this.publicAndPointlessEncapsulationMurderingGetterSetter
= publicAndPointlessEncapsulationMurderingGetterSetter;
//Seriously though Java/C# folks, stop with the pointless getter/setters already
function publicAndPointlessEncapsulationMurderingGetterSetter(arg){
if(arg === undefined){
return privateAndPersistent;
}
privateAndPersistent = arg;
}
}
ObjectConstructor.staticLikeNonInstanceProperty = true;
var instance = new ObjectConstructor();//Convention is to capitalize constructors
在我的代码中,我几乎从不使用对象文字{}
作为结构化应用程序组件,因为它们没有内部(私有)变量,而是更喜欢保留它们以用作数据结构。这有助于设定一个保持意图清晰的期望。(如果您看到curl,那是数据,而不是应用程序体系结构的组成部分)。
- 将参数传递给函数,无法知道该参数上有哪些属性和函数(除了实际运行程序之外,导航至调用该函数的位置,并使用console.logs输出所有属性可用)
再次,请参阅现代浏览器工具。但是,为什么再次运行该程序却如此笨拙呢?客户端Web开发人员通常每隔几分钟就会遇到Reload,因为这样做绝对不需要您花任何钱。再说一遍,应用程序结构可能会有所帮助,但这是JS的一个缺点,当执行合同很关键时,您必须运行自己的验证(我只在暴露于我的代码库所没有的其他事情的端点上这样做) 't控制)。IMO,权衡是值得的。
- 匿名函数通常用作回调,这经常导致混乱的代码路径,从而使您无法快速浏览。
是的,这对任何不平凡的事情都是不利的。不要那样做 给您的职能孩子起个名字。追踪事物也更容易。您可以在线定义,评估(需要分配)并分配简单的琐碎函数:
doSomethingWithCallback( (function callBack(){}) );
现在,当您跟踪通话时,Chrome将为您起一个名字。对于非平凡的函数,我将在调用之外定义它。还要注意,分配给变量的匿名函数仍然是匿名的。
- 可以肯定的是,JSLint在运行时会捕获一些错误,但即使那样,也不如直接在浏览器中的代码下具有红色波浪线那样方便。
我从不碰东西。Crockford给社区带来了一些好处,但是JSLint将这条线跨入了风格偏好,并暗示IMO的某些特定要素并不是没有很好的理由,而是不好的部分。绝对忽略与regEx和否定类有关的一件事,后跟*或+。通配符的性能更差,您可以轻松地用{}限制重复。另外,请忽略他关于函数构造函数的任何论述。如果新关键字困扰您,您可以轻松地将它们包装在工厂函数中。在坏建议方面,CSSLint(不是Crockford的)更糟。总是要用盐撒盐进行很多演讲活动的人。有时我发誓他们只是在寻求建立权威或产生新的材料。
同样,您必须通过运行时关注来学习所学到的知识。(这是我在许多Java / C#开发人员中所见过的常见现象)如果两年后仍然看到运行时错误困扰您,我希望您坐下来并在浏览器中重新加载垃圾邮件,直到它陷入。不是编译时/运行时的划分(无论如何也不是可见的-JS现在在JIT上运行)。不仅可以在运行时发现错误,而且以如此便宜的方式轻松地重新加载垃圾邮件并在到达的每个停止点都发现错误非常有益。
并开始使用那些Chrome开发人员工具。它们直接内置在webkit中。右键单击Chrome。检查元素。浏览选项卡。那里有足够的调试功能,并且可以在运行时更改控制台中的代码,这是最强大但不太明显的选项之一。也非常适合测试。
与此相关的是,错误是您的朋友。永远不要写空的catch语句。在JS中,我们不会隐藏或掩埋错误(或者至少我们不应该咳嗽 YUI / cough)。我们参加他们。减少任何内容都会导致调试困难。而且,如果您确实编写了catch语句以隐藏生产中的潜在错误,则至少应静默记录错误并记录如何访问日志。