javascript语法_使用现代JavaScript语法的最佳做法

javascript语法

本文在我们的《 JavaScript:最佳实践》 一书中有介绍 掌握快速变化的现代JavaScript最佳实践。

现代JavaScript正在Swift发展,以满足新框架和环境不断变化的需求。 了解如何利用这些更改可以节省您的时间,提高技能,并标记出好代码与好代码之间的区别。

了解现代JavaScript正在尝试做什么,可以帮助您决定何时使用新语法以发挥最大优势,以及何时仍然可以使用传统技术。

固执的东西

我不知道现在有谁对JavaScript的状态不感到困惑,无论您是JavaScript的新手,还是使用它进行编码已有一段时间。 如此众多的新框架,如此多的语言更改以及众多需要考虑的上下文。 每个人都能完成所有工作,这是每个月都要学习的新事物,这真是一个奇迹。

我相信,无论应用程序多么复杂,任何编程语言成功的秘诀都已经回到了基础。 如果您想了解Rails,请先学习Ruby技能,如果要在同构 ReactWebpack中使用不可变单向数据流 (或当今很酷的书呆子正在做的事情),首先要了解您的核心JavaScript。

与熟悉最新的框架和环境相比,了解语言本身的工作原理要实际得多。 那些变化比天气快。 有了JavaScript,我们就可以在线了解关于JavaScript是如何创建以及如何有效使用的悠久历史。

问题在于,最新版本JavaScript附带了一些新技术,使一些旧规则过时了。 但不是所有人! 有时,一种新语法可能会取代笨拙的语法来完成相同的任务。 在其他时候,新方法似乎是我们以前做事方式的简单替代,但是存在细微的差异,因此重要的是要知道它们是什么。

一勺语法糖

近年来,JavaScript的许多变化已被描述为现有语法的语法糖。 在许多情况下,语法糖可以帮助Java程序员学习如何使用JavaScript,或者对于我们其余的人,我们只需要一种更清洁,更简单的方法来完成我们已经知道的方法即可。 其他更改似乎引入了神奇的新功能。

但是,如果您尝试使用现代语法来重新创建熟悉的旧技术,或者在不了解其实际行为的情况下坚持使用它,则会冒以下风险:

  • 必须调试之前完美运行的代码
  • 引入可能会在运行时捕获您的细微错误
  • 创建您最不期望的代码而无声地失败。

实际上,似乎是对现有技术的直接替代的一些更改实际上在行为上与它们应替代的代码不同。 在许多情况下,使用原始的较旧的样式来完成您要尝试的工作可能会更有意义。 认识到何时发生并知道如何做出选择,对于编写有效的现代JavaScript至关重要。

当您的const不一致时

现代JavaScript引入了两个新的关键字letconst ,它们在大多数情况下在声明变量时有效地替换了对var的需求。 但是它们的行为与var完全不同。

在传统JavaScript中,在使用变量之前使用var关键字声明变量始终是一种干净的编码实践。 否则,您可能会在同一上下文中运行的任何脚本在全局范围内访问您声明的变量。 而且,由于传统JavaScript通常在可能同时加载多个脚本的网页上运行,因此这意味着一个脚本中声明的变量有可能泄漏到另一个脚本中。

let是现代JavaScript中最干净的var替代品。 但是, let有一些特质将其与var区分开。 默认情况下,带有var变量声明总是提升到其包含范围的顶部,无论它们在该范围内的什么位置。 这意味着即使是深度嵌套的变量也可以从其包含范围的开始就被认为是已声明并可用。 letconst并非如此。

console.log(usingVar); // undefined
var usingVar = "defined";
console.log(usingVar); // "defined"

console.log(usingLet); // error
let usingLet = "defined"; // never gets executed
console.log(usingLet); // never gets executed

使用letconst声明变量时,该变量的作用域仅限于声明该变量的本地块。 JavaScript中的块由一组花括号{}来区分,例如,函数的主体或循环内的可执行代码。

对于像迭代器和循环这样的变量进行块范围使用非常方便。 以前,在循环内声明的变量将可用于包含范围,从而在多个计数器可能使用相同的变量名时导致潜在的混乱。 但是,如果您希望在脚本的一个块内某个位置声明的变量在其他位置可用, let您感到惊讶。

for (var count = 0; count < 5; count++) {
  console.log(count);
} // outputs the numbers 0 - 4 to the console
console.log(count); // 5


for (let otherCount = 0; otherCount < 5; otherCount++) {
  console.log(otherCount);
} // outputs the numbers 0 - 4 to the console
console.log(otherCount); // error, otherCount is undefined

另一个替代声明是const ,它应该表示一个常量。 但这不是完全恒定的。

varlet变量不同,不能在没有值的情况下声明const

var x; // valid
let y; //valid
const z; // error

如果在声明const尝试将其设置为新值,则const也会抛出错误:

const z = 3; // valid
z = 4; // error

但是,如果您希望const在所有情况下都是不可变的,那么当声明为const的对象或数组允许您更改其内容时,您可能会感到惊讶。

const z = []; // valid
z.push(1); // valid, and z is now [1]
z = [2] // error

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

因此,当人们建议对所有变量声明始终使用const代替var时,即使您打算在声明它们后再也不要更改它们,我仍持怀疑态度。

虽然将变量视为不可变是一种很好的做法,但是如果没有外部脚本的帮助,JavaScript不会对引用变量(如数组和用const声明的对象)的内容强制执行此操作。 因此const关键字可能会使不经意的读者和JavaScript新手期望得到比其实际提供的更多保护。

我倾向于将const用于我想初始化且永不更改的简单数字或字符串变量,或用于我希望定义一次然后关闭以进行修改的命名函数和类。 否则,我将let用于大多数变量声明,尤其是那些我希望受其定义范围限制的声明。 我最近没有发现需要使用var ,但是如果我想要一个声明来打破范围并提升到脚本的顶部,这就是我要这样做的方式。

限制功能范围

可以调用使用function关键字定义的传统函数,以对传入的任何参数执行在块内定义的一系列语句,并可以选择返回值:

function doSomething(param) {
  return(`Did it: ${param}`);
}
console.log(doSomething("Hello")); // "Did it: Hello"

它们也可以与new关键字一起使用,以构造具有原型继承性的对象,并且该定义可以放置在范围内可以调用它们的任何位置:

function Animal(name) {
  this.name = name;
}
let cat = new Animal("Fluffy");
console.log(`My cat's name is ${cat.name}.`); // "My cat's name is Fluffy."

可以在调用它们之前或之后定义以这两种方式使用的函数。 JavaScript无关紧要。

console.log(doSomething("Hello")); // "Did it: Hello"

let cat = new Animal("Fluffy");
console.log(`My cat's name is ${cat.name}.`); // "My cat's name is Fluffy."

function doSomething(param) {
  return(`Did it: ${param}`);
}
function Animal(name) {
  this.name = name;
}

传统函数还创建自己的上下文, this定义一个值, this值仅存在于语句主体的范围内。 其中定义的任何语句或子函数都在执行,并且可以选择地允许我们在调用函数时this绑定一个值。

关键字要做的事情很多,而且通常在任何地方都超出了程序员的需求。 因此,现代JavaScript将传统函数的行为分为箭头函数和类。

准时上课

class关键字已取代了传统function一部分。 这使程序员可以选择是愿意遵循具有可调用箭头函数的功能更强大的编程范例,还是对类使用更具面向对象的方法来替代传统函数的原型继承。

JavaScript中的类的外观和行为与其他面向对象语言中的简单类非常相似,对于Java和C ++开发人员来说,当JavaScript扩展到服务器时,它们可以轻松扩展为JavaScript。

在JavaScript中进行面向对象编程时,函数和类之间的区别是JavaScript中的类需要前向声明,这是它们在C ++中的方式(尽管在Java中不是)。 也就是说,在使用new关键字实例化class需要在脚本中声明一个class 。 即使在脚本的后面定义了使用function关键字的原型继承,也可以在JavaScript中使用它,因为与class不同,因为function声明会自动提升到顶部。

// Using a function to declare and instantiate an object (hoisted)
let aProto = new Proto("Myra");
aProto.greet(); // "Hi Myra"

function Proto(name) {
  this.name = name;
  this.greet = function() {
    console.log(`Hi ${this.name}`);
  };
};

// Using a class to declare and instantiate an object (not hoisted)
class Classy {
  constructor(name) {
    this.name = name;
  }
  greet() {
    console.log(`Hi ${this.name}`);
  }
};

let aClassy = new Classy("Sonja");
aClassy.greet(); // "Hi Sonja"

带有箭头功能的尖锐差异

现在可以使用箭头函数来访问传统函数的其他方面,箭头函数是一种新语法,使您可以更简洁地编写可调用函数,以使其更整洁地适合回调函数。 实际上,箭头函数的最简单语法是单行,它完全省略了花括号,并自动返回所执行语句的结果:

const traditional = function(data) {
  return (`${data} from a traditional function`);
}
const arrow = data => `${data} from an arrow function`;

console.log(traditional("Hi")); // "Hi from a traditional function"
console.log(arrow("Hi"));  // "Hi from an arrow function"

箭头函数封装了几种特性,这些特性可以使调用它们更加方便,而忽略了其他一些在调用函数时没有用的行为。 它们不是更通用的传统function关键字的直接替代品。

例如,箭头函数从调用它的上下文中继承thisarguments 。 这对于事件处理或setTimeout这样的情况非常setTimeout当程序员经常希望将调用的行为应用于请求它的上下文中时。 传统功能迫使程序员编写卷积码,其结合到现有的功能this通过使用.bind(this) 。 箭头功能不需要这些。

class GreeterTraditional {
  constructor() {
    this.name = "Joe";
  }
  greet() {
    setTimeout(function () {
      console.log(`Hello ${this.name}`);
    }, 1000); // inner function has its own this with no name
  }
}
let greeterTraditional = new GreeterTraditional();
greeterTraditional.greet(); // "Hello "

class GreeterBound {
  constructor() {
    this.name = "Steven";
  }
  greet() {
    setTimeout(function () {
      console.log(`Hello ${this.name}`);
    }.bind(this), 1000); // passing this from the outside context
  }
}
let greeterBound = new GreeterBound(); // "Hello Steven"
greeterBound.greet();

class GreeterArrow {
  constructor() {
    this.name = "Ravi";
  }
  greet() {
    setTimeout(() => {
      console.log(`Hello ${this.name}`);
    }, 1000); // arrow function inherits this by default
  }
}
let greeterArrow = new GreeterArrow();
greeterArrow.greet(); // "Hello Ravi"

了解您所得到的

不仅仅是语法糖。 由于需要新功能,因此引入了JavaScript的许多新更改。 但这并不意味着JavaScript传统语法的旧原因已经消失。 继续使用传统JavaScript语法通常很有意义,有时使用新的语法可以使您的代码编写起来更快,更容易理解。

查看您正在关注的那些在线教程。 如果编写者使用var初始化所有变量,忽略类以支持原型继承或依赖于回调中的function语句,则可以期望其余语法基于旧的传统JavaScript。 很好。 今天,我们仍然可以从传统JavaScript教导和使用方式中学到很多东西并应用它们。 但是,如果在初始化中看到letconst ,在回调函数中使用箭头函数,并在类中将其作为面向对象模式的基础,那么您可能还会在示例中看到其他现代JavaScript代码。

现代JavaScript的最佳做法是注意语言的实际作用。 根据您的习惯,可能并不总是很明显。 但是,请考虑一下您正在编写的代码将要完成什么,需要在哪里部署它以及下一步将由谁修改。 然后自己决定最好的方法是什么。

翻译自: https://www.sitepoint.com/modern-javascript-best-practices/

javascript语法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值