JavaScript Best Practices and Tips by Toptal Developers

Share

这个资源包含了由Toptal网络成员提供的JavaScript最佳实践和JavaScript技巧的集合.

这个资源包含了由Toptal网络成员提供的JavaScript最佳实践和JavaScript技巧的集合, 并将定期更新其他信息和新兴的JavaScript技术. This is a community-driven project, so we encourage you to contribute as well, and we are counting on your feedback.

JavaScript专家的最佳实践在网上不难找到, 由于这种动态编程语言的流行. 然而,通过采用最新的JavaScript建议,我们认为我们可以做得更好.

看看Toptal 资源页面 欲知更多有关 JavaScript中的常见错误,一个JavaScript 招聘指南, JavaScript 工作描述 和JavaScript 面试问题.

如何使用立即调用的函数表达式避免全局作用域污染?

在JavaScript中声明全局作用域变量是一种不好的做法, and is often referred to as global scope pollution. 避免全局作用域污染的解决方案之一是使用立即调用的函数表达式, 或简称生命. IIFE basic code example looks like this:

    (function () {
        //做有趣的事情
    })()

以这种方式声明的函数是一个匿名函数表达式, and is immediately and automatically invoked.

IIFE是如何工作的,匿名函数是如何被立即调用的? 围绕匿名函数的一对括号将其转换为函数表达式, 或者变量表达式. 结果是一个具有自己作用域的未命名函数表达式.

IIFE的使用非常简单. 当你创造生活, 该函数中的每个变量定义都只存在于该作用域中, like a modularization or isolation of the data. IIFE declaration example can look like this:

    (函数(){
        Var my_data = ";
        Var init = function(){
		//做点什么
        };

	  init()

    })(); //This IIFE will be invoked and executed automatically, without the need to call by yourself

这样,就根本不需要声明全局作用域变量. 在匿名函数中声明的每个变量都可以在自己的作用域中轻松访问, 同时,它保持全局命名空间的整洁. 这很重要,因为它避免了与其他库的任何潜在冲突, 或者用我们自己的代码.

除此之外,IIFE最流行的用法是拥有一个干净的全局作用域, 使用IIFE的另一个好处是,它将代码保存在独立的模块中. How? 与生活任何 var declared inside isn’t accessible from the outside. 生命只是一个函数, 所以它可以返回任何东西, 和每个函数一样, which enables you to create your own modules like this:

var mySuperModule = (函数(){
    var myVar = '一些字符串';
    
    var privateFunction = function (){
	/ /做某事
    };
    return {
	getMyVar:函数(){
		返回myvar#
      }
    };
})();

现在是变量 myVar 只存在于 mySuperModule, which can even have private and public methods.

Many libraries use this technique (like jQuery), 建议至少在应用程序的顶层使用它.

To learn more on the subject, you can read 本·阿尔曼的文章, 掌握模块模式, or Essential JavaScript Namespacing Patterns.

Get the latest developer updates from Toptal.

Subscription implies consent to our 隐私政策

How to Compare Two URLs from JSON for Equality

在任何语言中比较两个字符串是否相等听起来都像是一件简单的任务——你只需要使用相等运算符(==). 在JavaScript中,最佳实践是使用严格相等操作符(===),其行为与简单相等运算符(==), except no type conversion is done. 当使用严格相等运算符时,对象类型必须相同才能被视为相等. 另一方面, 简单相等操作符将首先尝试强制值,然后进行比较.

这在理论上听起来很棒, 但是当你面对下面的问题时该怎么做:你知道你要比较的输入值是相等的, 但是JavaScript相等运算符告诉你它们不是?

在我们的例子中, we are parsing two JSONs from separate sources, 我们试着看看它们的链接属性是否相同. 当我们在控制台中打印JSON链接属性时,它们看起来是一样的,但是仍然, a.link == b.link 返回false. Notice we are not using strict equality operator here, 因此,即使JSON链接属性对象类型不相同,事情也应该更简单, 这里是字符串. 如果我们进一步测试在控制台中打印的值并比较它们,它们将是相等的. Keeping your sanity is important here. 也许你现在正在用你的头撞键盘,但是跟上我们. The problem is that they are unequal before printing.

这个问题的解决方案非常简单:我们必须准备输入JSON数据,而不是假设我们得到的是有效字符串. 由于我们处理的是url,因此必须首先使用 encodeURIComponent () function, like in the following example:

console.log( encodeURIComponent('http://www.example.com/ '));
> "http%3A%2F%2Fwww.example.com%2F"

这个“丑陋”但URL友好的东西现在被标准化并正确编码了. To make our URL readable again, we can use unescape () function:

console.log( unescape(encodeURIComponent('http://www.example.com/ ')));
> "http://www.example.com/"

This way, 如果一个URL在某处缺少编码而另一个没有, they will finish in the end as the same strings:

console.log( unescape(encodeURIComponent(a.link)) == unescape(encodeURIComponent(b.link)) );

Output in the console now will be true.

贡献者

克丽丝Powelski

自由JavaScript开发者

France

Kris是一名充满激情的开发者,有着一种天才的气质. 他在10岁时编写了自己的第一款电子游戏,之后不久便投身于网页开发. Kris喜欢与国际团队合作,在他的桌面体验世界,并成为令人兴奋的项目的一部分.

显示更多

亚历克斯Covaci

自由JavaScript开发者

Romania

Alex是一位经验丰富的开发人员, 自行出版者, 以及具有开发和发布复杂软件产品能力的企业家, 跨越多个平台. 不管手头有什么任务, 他总是会把他的激情和对细节的关注带到桌子上.

显示更多

我如何确定文本片段的长度,将适合一个给定的元素?

Imagine you have some text of arbitrary length, 你想要确定这个文本的前缀的长度适合放在 div element of given width and height. 事实证明,这是在试图操纵网页呈现时出现的那些看似棘手的问题之一.

One 可能的解决方案 是创造一个相同的 div, 高度或宽度未设置的, 然后尝试给定字符串的所有可能的前缀长度看看哪个会带来new的高度 div 接近原来的那个.

This solution works for most cases, but, 神秘的, 当任何特定于html的字符出现在文本末尾时失败. 事实上,这种情况甚至可能导致页面崩溃! 这种行为的原因, 事实证明, 元素的innerHTML属性的行为不像你期望的任何典型的对象属性. 例如,如果你要分配的话 & 到a的innerHTML div element, the browser would eventually convert this to &. 因此,添加 & 在大文本的末尾附近会导致循环总是试图删除后缀的情况 p; from &, and the browser would immediately turn it into &am. 这种效果会不断重复,形成一个永无止境的循环!

如果您试图在某些文本片段上创建省略号效果, 通常, 你只需要一个 几行CSS - given that your text will all appear on a single line. 然而,对于多行文本,我们可以使用JavaScript,而且JavaScript通常更有意义.

对上面的部分解决方案做一个小的改变就可以解决特殊字符引起的问题. 而不是使用 boxCl.innerHTML,你可以用 boxCl.textContent:

// ...
boxCl.textContent =文本
document.body.列表末尾(boxCl)
而(boxCl.clientHeight > box.clientHeight) {
    boxCl.textContent = boxCl.textContent.substring (0, boxCl.textContent.length-1)
}
box.textContent = boxCl.textContent

This 解决了无限循环问题 公正的. 你也可以直接 使用原始字符串变量 to determine the substring on every iteration. 这样,您就可以添加像'…'这样的尾随字符串而不会出现任何问题. Moreover, 如果你想, 您可以更进一步,用二进制搜索替换原始循环. 如果你仔细想想, 像这样的简单循环, 在最坏的情况下,长达1000个字符的文本片段将需要近1000次尝试. A 基于二分搜索的解 will work the same thing out in about 10 tries.

贡献者

卡洛斯Minatti

自由JavaScript开发者

阿根廷

卡洛斯热衷于互联网和通信技术,并寻找帮助人们解决日常问题的方法. 他在构建web和Android应用方面有着丰富的经验, 并始终致力于提供最好的用户体验.

显示更多

约翰·金斯堡

自由JavaScript开发者

联合王国

John是一名开发人员和企业家,拥有15年以上的编程实践经验. He has worked on a variety of projects, including developing large-scale websites, 一个电子邮件营销平台,每天发送数百万封电子邮件, and social media integration with Facebook, Twitter, 和LinkedIn.

显示更多

理查德煤尘

自由JavaScript开发者

南非

理查德是一个友好、健谈、外向、聪明的人,喜欢解决问题. He carefully assesses the requirements of a task, 抓住机会仔细思考,并有效地生产易于维护和完整的产品.

显示更多

严格使用strict

您是否发现自己在一个不利于现代JavaScript的环境中工作, 这个关于“严格使用”指令的提示是给你的. 使用ES6或转译器编写代码的开发人员不需要继续阅读.

严格地说,“使用严格的”模式在很多方面都有帮助. 这个指令通过强制执行声明变量之类的东西,在JavaScript编程的狂野西部强加了一些法律和秩序, 不允许保留关键字并防止使用 with 语句. strict指令可以应用于整个脚本,也可以包含在函数的作用域中.

养成使用“使用严格的”指令的习惯,因为它可以帮助你编写更好的代码, 代码对测试更友好,对下一个程序员来说更容易. Strict code also offers assistance when optimizing since it is less error prone; it will help you in the long run since ES6 modules already enforce strict mode. To learn more, I recommend reading Mozilla’s reference on Strict Mode 以便更好地理解在JavaScript中使用严格模式.

也就是说,在实施时 使用严格的, 重要的是将它封装在一个匿名函数中,以避免全局设置它, which can cause unexpected behaviors.

/ / myGreatApp.js
“使用严格的”; // could have unforeseen effects

(函数(){
    “使用严格的”;
    //做不可思议的事
})();

贡献者

Lavi Yatziv

自由JavaScript开发者

Canada

Lavi是一位世界级的前端开发人员,曾在汉莎航空等企业级组织工作过, Okta, 和德保罗大学. 在考虑时间限制的情况下,他非常小心地提供最好的解决方案. 他在动态图形动画方面的教育为最终用户提供了广泛的UI词汇表. 调试和改进遗留代码的功能是Lavi的专长之一, making him a versatile and innovative software engineer.

显示更多

What Is the Best Tool for Drawing Graphs and Diagrams?

假设你是一个前端开发人员,你需要绘制漂亮的图形和图表, 比如二叉树结构. They obviously need to be interactive and filterable. 你会从哪里开始?? 你会用什么工具? 最近,Toptal开发人员就这个话题进行了讨论. After some long nights and many arguments, a final conclusion was reached: at the moment, the best tool for drawing graphs and diagrams is D3.js.

D3是什么?.js then? 简而言之, D3.js 是数据可视化库吗. D3.js允许开发人员基于输入数据轻松地生成和操作DOM元素, 并为从头开始开发矢量数据可视化提供了强大的工具. 它的想法是弥合静态数据显示与交互式和动画数据可视化之间的差距, 通过使用JavaScript, CSS, HTML和SVG. The result can be simple HTML output, 或具有动画等动态行为的交互式SVG图表, 转换, 和交互. 所有的数据转换和呈现都是在浏览器的客户端完成的. D3.js is also open sourced, and extensible via plugins.

只要记住D3.Js不是一个容易掌握的工具,它有一个陡峭的学习曲线. 开发人员需要熟悉很多技术, 即JavaScript对象, jQuery链接语法, SVG和CSS, 当然 D3’s API. 最重要的是,一个人需要有一点设计技巧,最终创造漂亮的图形. 幸运的是,D3.js has a big community, and there are a lot of 参考资料和教程 让人们去挖掘.

所以下次你发现自己面对一个有图表的项目,而你没有合适的工具, 抓一个D3.让你的想象力成为你创作的唯一限制.

Meteor: The Good, The Bad, The Ugly

For a long time, I’ve been working with Node.js and Express on the server side, 以及用于前端开发的jQuery和其他流行的JavaScript框架. 不久前,我开始为一家公司工作,该公司80%的项目都在使用Meteor. 在我学习和使用Meteor一段时间后,我觉得这是在错误的方向上迈出的一步. 在你拿出干草叉和火把之前,让我解释一下原因.

The Good

同构和通用的应用程序

与后端代码共享客户端代码可能是目前的终极目标. 在浏览器和服务器上运行相同的代码非常方便. 我们将分享一些通常被称为“业务逻辑”的JavaScript文件:即控制器, models, 验证,甚至常数. 这为我们在后端重新实现相同的前端逻辑节省了时间和精力.

Minimongo

Minimongo简直太神奇了. 在浏览器中拥有一个完整的类似MongoDB的接口,其行为就像一个完整的MongoDB数据库. 只需打开浏览器的开发者控制台,我们就可以在浏览器中检查整个数据库. 即使在调试模式下,当我们更改值时,它也会自动与后端数据库同步. To some degree it feels very similar to PouchDB一个受couchdb启发的数据库. When comparing PouchDB directly to Minimongo, I feel Minimongo has the upper hand, mostly because querying for data requires less effort.

The Bad

包管理

Meteor自带名为Atmosphere的软件包管理系统. 问题是,大多数包含流行库的包都不是由其原作者在Atmosphere上维护的. 这将导致您不知道包实际包含什么,以及它是否像原始模块一样定期更新. 有些软件包甚至可能包含比官方发行版更多的内容,而有些则更少.

模块管理

The notion of modules does not exist in Meteor at all. Meteor按照文件系统中存在的字母顺序加载所有文件. 我曾见过这样的项目,其中文件名的前缀很有趣, 比如下划线, double underscores or numerical identifiers, 或者是这些的组合.

您实际上是在服务器端和客户端使用全局变量. 结果是, 你几乎必须处理你在模块之前必须处理的一切(比如CommonJS), AMD或ES2015)成为流行和事实上的标准.

因为您无法控制何时加载客户端脚本, 您需要在全局范围内检查您自己的脚本和第三方库. This is my most prominent and major gripe with Meteor. Meteor gives us a default load order for our libraries, 但在某些情况下,我们需要改变这一点, 例如,当我们有多个相互依赖的库时. 使用流行的模块选项, we need to define our imports and exports explicitly, 但这增加了模块的可预测性,我们知道哪些模块相互作用. 在Meteor中,我们没有这样做,如果我们不够小心,这可能会导致副作用.

The Ugly

执行不良做法

对于在服务器和客户端都可用的变量,我们省略 var keyword when defining that variable. While Meteor bundles the JavaScript files for us, 它将函数包装在JavaScript代码周围,并插入 var 给我们的声明. This will be safe in the end result, 但它仍然给人一种利用JavaScript缺陷的感觉.

Compatibility with Node libraries

Meteor使用了一个名为 Fibers 控制流. 在Meteor中,几乎所有异步操作都感觉是同步的,并以这种方式定义. 通常回调, promises, 生成器和async/await是处理异步性的主要解决方案. 异步性是JavaScript的一个核心概念,也是我看到许多开发者都在纠结的一个概念. 由于Node中的库之间存在巨大的差距.js和Meteor处理控制流,兼容性并不总是给定的. 虽然Meteor可以与大多数NPM库一起工作,但反过来就很难了.

大气是闭源

Atmosphere不是开源的. While this in itself may not necessarily be an issue, 我不禁想知道,如果Meteor背后的公司不复存在,会发生什么. 谁将接管Atmosphere,提供维护和支付费用?

Wrap up

There are some minor gripes I have with Meteor, 例如,在某些情况下,我觉得它的文档并不像我希望的那样全面, 或者有些东西可能会被误解——尤其是对那些刚开始接触JavaScript世界的人来说.

总之, 我觉得《欧博体育app下载》被它最初的设计决定卡住了, 从那以后,它的发展并没有像它应该的那样激进. As much as we crucify the Angular 1.x to 2.X版本的变化及其或多或少的完全重新设计, I feel something like that might actually help Meteor. 而Meteor则在其最新版本中拥抱ES2015, 我希望看到更多这些概念被带到Meteor:使用ES2015模块系统, ES2016’s async/await syntax 控制流, 类装饰器和更好的UI组件概念是我想到的一些想法.

如果Meteor是一个Express中间件,并且我能够指定和控制某些方面,我会有不同的看法吗. 例如, specify how and which files get loaded, 而不是抽象到一个看似“黑盒”. 肯定.

贡献者

约翰内斯·斯坦

自由JavaScript开发者

联合王国

Johannes是一位精通JavaScript的高技能软件工程师, 网络技术, 以及跨平台开发. 他对开源软件充满热情,并且精通软件架构.

显示更多

How to Use Promises in JavaScript as an iOS Developer?

许多开发人员主要专注于一种技术,他们是该领域的大师. Due to the nature of the software developer’s job, 他们需要不时地了解他们不太熟悉的技术,并使用他们还不知道的编程语言.

假设你是一名iOS开发者,你需要使用JavaScript完成一个快速任务并使用Parse Cloud Code. 你认为这很容易. 你知道如何使用Objective-C实现它,但你没有任何使用JavaScript的经验. 根据你使用Objective-C的经验,第一次尝试可能会这样结束:

Parse.Cloud.define("myName", function(request, response){
 
  var myID =请求.params.myID;
  var myQuery =新的解析.查询(“myQuery”);

  myQuery.first( {
    成功:function(r) {
      r.save({"someID": myID}).然后(函数(newR) {
        //做一些事情
      },
      函数(err) {
        response.错误(错误);
      });
    },
    函数(err) {
      response.错误(错误);
    });
  },
  错误:函数(err) {
    response.错误(错误);
  });

});

说实话吧, this code is a mess; there are way too many nested functions, 大量的面条式代码, and multiple error entry points are all over the code.

一个没有经验的开发人员一开始没有意识到的是,通过在JavaScript中使用承诺, you don’t need to endlessly nest your functions. 承诺也可以被捆绑. Pseudo code would look like this:

x
  .然后(function() {return y()})
  .然后(function() {return z()})
  .catch(function() { /* oh no, error! */ });

在上面的例子中, x, y and z 都在返回承诺. 虽然,这是不需要的 y and z 回报承诺. 这里更重要的一点是,错误现在会冒泡到父节点.

带着新知识回到我们的第一个例子,最终的工作代码看起来像这样:

Parse.Cloud.define("myName", function(request, response){

  var myID =请求.params.myID;
  var myQuery =新的解析.查询(“myQuery”);

  // Here's where things go Promises.
  myQuery
    .first()
    .然后(函数(r) {
      return r.save({"someID": myID});
    })
    .然后(函数(newR) {
      var countQuery = new Parse.查询(“myQuery”);
      返回countQuery.数(newR);
    })
    .然后(函数(数字){
        If (number === 0) {
          //做一些事情
        }
    })
    .抓住(函数(错误){
      response.错误(错误);
    });

});

iOS开发者的新体验是你可以调用函数并在next然后段中处理回调. JavaScript开发者经常使用promise,但iOS开发者则不然.

这个例子不仅适用于需要深入研究JavaScript的iOS开发人员. Parse 也支持Android, Windows Phone, Unity, 和Xamarin的, 所以来自这些平台的任何开发者都可能面临同样的情况. Or just any developer that is new into JavaScript.

贡献者

理查德煤尘

自由JavaScript开发者

南非

理查德是一个友好、健谈、外向、聪明的人,喜欢解决问题. He carefully assesses the requirements of a task, 抓住机会仔细思考,并有效地生产易于维护和完整的产品.

显示更多

提交建议

提交的问题和答案将被审查和编辑, and may or may not be selected for posting, 由Toptal全权决定, LLC.

*所有字段均为必填项

Toptal连接 Top 3% of Freelance Talent All Over The World.

加入Toptal社区.