前端 ES6 语法-1

  • 概述 JS 语法的变化和添加
  • JS 函数的更新
  • 新的 ES6 内置功能
  • 如何将这些更新整合到 JS 项目中

JavaScript 编程语言的全新变化,Harmony、ES6 和 ES2015 它们只是同一事物的不同名称,重要的是,这些名称代表 JavaScript 编程语言的更新,经历了一些大刀阔斧的必要改进,随着这些改进,产生了一批新的关键字、编写函数的方法和异步简便方法等等。接下来我们将介绍 JS 编程语言添加的新功能,使我们可以更快捷、简洁和高效地编写代码。

JS 语法的变化和添加

letconst

从现在开始,建议放弃使用 var,改为使用 let 和 const。为了理解为何添加了 let 和 const,我们先看一个示例,了解使用 var 会带来怎样的麻烦。

function getClothing(isCold) {
  if (isCold) {
    var freezing = "Grab a jacket!";
  } else {
    var hot = "It's a shorts kind of day.";
    console.log(freezing);
  }
}
getClothing(false);
// 输出:undefined

提升 是浏览器解析 JavaScript 的结果。本质上,在执行任何 JavaScript 代码之前,所有变量都会被“提升”,也就是提升到函数作用域的顶部。因此在运行时,getClothing() 函数实际上看起来如下所示…

function getClothing(isCold) {
 var freezing, hot;
  if (isCold) {
    freezing = "Grab a jacket!";
  } else {
    hot = "It's a shorts kind of day.";
    console.log(freezing);
  }
}
getClothing(false);
// 输出:undefined

使用 letconst 声明的变量解决了这种提升问题,因为它们的作用域是到块,而不是函数。之前,当你使用 var 时,变量要么为全局作用域,要么为本地作用域,也就是整个函数作用域。

如果在代码块(用花括号 { } 表示)中使用 let 或 const 声明变量,那么该变量会陷入暂时性死区,直到该变量的声明被处理。这种行为会阻止变量被访问,除非它们被声明了。

function getClothing(isCold) {
  if (isCold) {
    let freezing = "Grab a jacket!";
  } else {
    let hot = "It's a shorts kind of day.";
    console.log(freezing);
  }
}
getClothing(false);
// 输出:Uncaught ReferenceError: haha is not defined

关于使用 letconst 的规则:

  • 使用 let 声明的变量可以重新赋值,但是不能在同一作用域内重新声明
  • 使用 const 声明的变量必须赋初始值,但是不能在同一作用域内重新声明,也无法重新赋值

最大的问题是何时应该使用 letconst?一般法则如下:

  • 当你打算为变量重新赋值时,使用 let
  • 当你不打算为变量重新赋值时,使用 const

因为 const 是声明变量最严格的方式,我们建议始终使用 const 声明变量,因为这样代码更容易读懂,你知道标识符在程序的整个生命周期内都不会改变。如果你发现你需要更新变量或更改变量,则回去将其从 const 切换成 let

const CHARACTER_LIMIT = 255;
const posts = [
    "#DeepLearning transforms everything from self-driving cars to language translations. AND it's our new Nanodegree!",
    "Within your first week of the VR Developer Nanodegree Program, you'll make your own virtual reality app",
    "I just finished @udacity's Front-End Web Developer Nanodegree. Check it out!"
];

// prints posts to the console
function displayPosts() {
    for (let i = 0; i < posts.length; i++) {
        console.log(posts[i].slice(0, CHARACTER_LIMIT));
    }
}

displayPosts();

模版字面量

在 ES6 之前,将字符串连接到一起的旧方法是使用字符串连接运算符 (+)。

const student = {
  name: 'Richard Kalehoff',
  guardian: 'Mr. Kalehoff'
};

const teacher = {
  name: 'Mrs. Wilson',
  room: 'N231'
}

let message = student.name + ' please see ' + teacher.name + ' in ' + teacher.room + ' to pick up your report card.';

作为字符串连接运算符 ( + ) 的替代方法,你可以使用字符串的 concat() 方法。但是这两种方式都比较笨拙。

模板字面量本质上是包含嵌入式表达式的字符串字面量

let message = `${student.name} please see ${teacher.name} in ${teacher.room} to pick up your report card.`;

模板字面量用倒引号 ( ` )(而不是单引号 ( ’ ) 或双引号( “” ))表示,可以包含用 ${expression} 表示的占位符,这样更容易构建字符串。

// +
let note = teacher.name + ',\n\n' +
  'Please excuse ' + student.name + '.\n' +
  'He is recovering from the flu.\n\n' +
  'Thank you,\n' +
  student.guardian;
// ${}
let note = `${teacher.name},

Please excuse ${student.name}.
He is revovering from the flu.

Thank you,
${student.guardian}`;
/**
输出:
Mrs. Wilson,

Please excuse Richard Kalehoff.
He is recovering from the flu.

Thank you,
Mr. Kalehoff
*/

这是模板字面量的真正强大之处。在上述动画中,去掉了引号和字符串连接运算符,以及换行符 ( \n )。这是因为模板字面量也将换行符当做字符串的一部分!

注意:模板字面量中的嵌入式表达式不仅仅可以用来引用变量。你可以在嵌入式表达式中进行运算、调用函数和使用循环

解构

在 ES6 中,你可以使用解构从数组和对象中提取值并赋给独特的变量

// 解构前提取数据
const point = [10, 25, -34];

const x = point[0];
const y = point[1];
const z = point[2];
console.log(x, y, z);

// 解构后提取数据
const point = [10, 25, -34];
const [x, y, z] = point;
console.log(x, y, z);

在此示例中,方括号 [ ] 表示被解构的数组,x、y 和 z 表示要将数组中的值存储在其中的变量。注意,你不需要指定要从中提取值的索引,因为索引可以暗示出来。

注意,在解构数组时,还可以忽略值。例如,const [x, , z] = point; 忽略了 y 坐标。

// 解构前提取数据
const gemstone = {
  type: 'quartz',
  color: 'rose',
  karat: 21.29
};
const type = gemstone.type;
const color = gemstone.color;
const karat = gemstone.karat;
console.log(type, color, karat);
// 解构后提取数据
const gemstone = {
  type: 'quartz',
  color: 'rose',
  karat: 21.29
};
const {type, color, karat} = gemstone;
console.log(type, color, karat);

在此示例中,花括号 { } 表示被解构的对象,type、color 和 karat 表示要将对象中的属性存储到其中的变量。注意不用指定要从其中提取值的属性。因为 gemstone 对象具有 type 属性,值自动存储在 type 变量中

注意,你还可以指定在解构对象时要选择的值。例如,let {color} = gemstone; 将仅选择 gemstone 对象中的 color 属性。

const circle = {
  radius: 10,
  color: 'orange',
  getArea: function() {
    return Math.PI * this.radius * this.radius;
  },
  getCircumference: function() {
    return 2 * Math.PI * this.radius;
  }
};

let {radius, getArea, getCircumference} = circle;
/**
undefined
radius
10
getArea
ƒ () {
    return Math.PI * this.radius * this.radius;
  }
getCircumference
ƒ () {
    return 2 * Math.PI * this.radius;
  }
getArea();
NaN
getCircumference();
NaN*/

在此示例中,调用 getArea() 将返回 NaN。在解构该对象并将 getArea() 方法存储到 getArea 变量中时,它无法再访问 circle 对象中的 this,得出面积 NaN

对象字面量简写法

ES6 中经常出现的一个现象是删掉不必要的重复代码。通过删掉不必要的重复代码,代码更容易读懂,并且更简练。推出的新简写法(用来初始化对象并向对象中添加方法)就是这一体现。

let type = 'quartz';
let color = 'rose';
let carat = 21.29;

const gemstone = {
  type: type,
  color: color,
  carat: carat
};

console.log(gemstone);

看到重复的地方了吗?type: typecolor: colorcarat:carat 不显得很冗长吗?

如果属性名称和所分配的变量名称一样,那么就可以从对象属性中删掉这些重复的变量名称

let type = 'quartz';
let color = 'rose';
let carat = 21.29;
const gemstone = { type, color, carat };
console.log(gemstone);

还有一种向对象中添加方法的简写方式:

let type = 'quartz';
let color = 'rose';
let carat = 21.29;

const gemstone = {
  type,
  color,
  carat,
  calculateWorth: function() {
    // 将根据类型(type),颜色(color)和克拉(carat)计算宝石(gemstone)的价值
  }
};
// 简写
let gemstone = {
  type,
  color,
  carat,
  calculateWorth() { ... }
};

真的需要 function 关键字吗?在 ES6 中不需要!只需引用 gemstone 对象的 calculateWorth 属性以便调用该函数,因此关键字 function 是多余的,可以删掉。

总结

通过上面的学习,我们学会了使用 let 和 const 声明变量的新方法,如何编写模版字面量以方便字符串插值,解构数组和对象以及初始化对象的一些便捷方法。

你可能感兴趣的:(前端开发入门)