与任何其他编程语言一样,JavaScript有自己的最佳实践列表,使程序更易于阅读和维护。因为JavaScript有很多小陷阱,所以要小心避免它们。遵循一些最佳实践可以使JavaScript代码易于阅读。本文将介绍需要避免的误区,例如声明全局变量、将字符串传递给setInterval和setTimeout、使用with语句等。避免声明全局变量无论出于何种原因,都应尽可能避免使用全局变量。一是它们很容易在不同的地方被覆盖,因为全局变量随处可用。另外,全局变量是window对象的属性,也可以覆盖window对象的内容。这两个问题会使代码难以执行。因此,您应该定义尽可能多的局部变量。可以使用var、let或const关键字定义局部变量。使用var定义的变量在定义之前在定义级别和以下级别可用。例如下面的代码:constlog=()=>{console.log(x);}log();varx=1;log();代码中,第一个console.log中的x为undefined,第二个alog中的x为1,等价代码如下:varx;constlog=()=>{console.log(x);}log();x=1;log();用let声明的变量只在定义后才可用,所以如果给出如下代码:constlog=()=>{console.log(x);}log();letx=1;log();会出现如下错误信息:UncaughtReferenceError:Cannotaccess'x'beforeinitialization使用const关键字定义了一个只能赋值一次且不能重新赋值的常量。与var不同,此类常量只有在声明后才可用。例如,以下代码:{console.log(x);}constx=1;log();在constx=1之前调用log也会导致如下错误信息:UncaughtReferenceError:Cannotaccess'x'beforeinitialization如果你想在程序部分有所不同,你应该使用JavaScript模块,然后在发布时将那些模块构建成一个或多个大文件你的代码。这个方法从ES6开始可用。变量可以导出和导入到其他模块中。也可以使用“ExportDefault”导出整个模块。这样只有在模块外部应该可用的部分才会被导出,其他一切都是不可见的。此外,您可以使用闭包将变量存储在函数中,从而避免外部调用。下面用于简单的闭包:=()=>{constx=3;return()=>x*2;}在divide函数中保留x避免外部调用,返回一个处理x的函数。然后编写如下代码调用:console.log(divide()());不要将字符串传递给setInterval或setTimeout不要将字符串传递给setInterval或setTimeout函数的第一个参数,而是传递回调函数。如果传递的是字符串而不是回调函数,浏览器会使用eval来运行字符串中的代码,速度慢且容易被代码注入。因此,除非我们真的需要运行动态生成的代码,否则没有理由执行上述操作,但这应该是非常非常罕见的情况。下面的代码不要写:setTimeout(()=>{document.getElementById('foo').textContent='foo';},1000);应该写如下代码:setTimeout(()=>{document.getElementById('foo').textContent='foo';},1000);不要使用“with”语句从表面上看,with语句似乎是访问对象的深层嵌套属性的好捷径。例如,你可以这样写:letobj={foo:{bar:{baz:1}}}obj.foo.bar.baz=2;而不是:letobj={foo:{bar:{baz:1}}}with(obj.foo.bar){varbaz=2;}但即使这样也会干扰全局对象,并使baz是否可以在外部访问变得模糊with语句。因为在with语句中也可以声明新的变量:letobj={foo:{bar:{baz:1}}}with(obj.foo.bar){varbaz=2;}其中baz变量声明在with里面statement,但不能被外部调用。幸运的是,with语句在JavaScript严格模式下是不允许的,所以暂时不用担心。var关键字在ES6中,变量和常量可以分别使用块作用域的let和const关键字来声明。之所以可以用它们来声明变量,是因为它们有明确的作用域。用var声明的变量的使用范围比较模糊。如果在if块或循环等程序块内声明,则声明的变量在块外可用。例如:for(leti=0;i<10;i++){varj=i;}console.log(j);这种情况下使用var是可行的,但是如果使用let而不是var来声明变量,就会报错。由于范围不明确,我们应该停止使用var来声明变量。在使用JavaScript编程时,我们希望避免早期JavaScript版本中存在的许多遗留结构。使用这些结构会使代码难以阅读并且容易出现错误。首先避免全局变量声明,以防止在全局范围内意外引用和声明事物。这也减少了意外修改全局变量值的可能性。其次,您应该停止以字符串形式传递代码,而是传递一个回调函数作为setTimeout和setInterval函数的第一个参数。因为eval将用于运行存储在字符串中的代码,这使程序容易受到代码注入攻击,而且速度也很慢。还要避免使用with语句,因为它会在全局对象内创建变量。此外,您应该避免使用var关键字声明变量,因为使用var关键字声明的变量范围不明确。
