文章目录

  • 简介
  • ECMAScript和JavaScript的关系
  • let和const
  • 解构赋值
  • 数组的扩展
  • 函数的扩展

简介

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,正式发布与2015年6月。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

今天我们将会讲解一下ES6中引入的语法新特性。

ECMAScript和JavaScript的关系

1996年11月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给国际标准化组织ECMA.

1997年, ECMA 发布262号标准文件 ECMAScript 1.0。

ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。

我们看一下ECMAScript的发行历史:

从2015年ES2015,也就是ES6发布以来,ECMAScript以每年一个版本的发行速度发行到了ES2020。

后面的文章我们会讲解一下这些新版本的ECMAScript的新特性。

let和const

ES6中引入了let和const,是为了解决之前的var变量的种种问题。

在ES6之前,JS中变量的作用域有两种:全局作用域和函数作用域。

全局作用域很好理解,我们在浏览器控制台或者 Node.js 交互终端中开始编写 JavaScript 时,即进入了所谓的全局作用域。

全局作用域的变量可以在任何其他作用域中访问。

函数作用域就是定义在函数内部的变量,在函数内部都可以访问到该变量。

这两种作用域会有一些问题:

  1. 变量提升

var命令会发生”变量提升”现象,即变量可以在声明之前使用,值为undefined.

// var 的情况
console.log(foo);  // 输出undefined
var foo = 2;
  1. 变量覆盖

当我们在函数作用域使用全局变量的时候,如果函数作用域中定义了同样名字的变量,不管是在哪里定义的,都会覆盖掉全局的变量。如下所示:

var tmp = new Date();
function f() {
console.log(tmp);
if (false) { var tmp = "hello world";
} }
f(); // undefined
  1. 变量泄露

变量泄露的意思是,我们本来只希望在小范围作用域使用的变量,结果泄露到了范围外面,如下所示:

var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
~~为了解决上面两个问题,ES6引入了let和const。这两个都是块级作用域。不同的是const定义的变量初始化之后就不能变化了。什么是块级作用域呢?类似于 if、switch 条件选择或者 for、while 这样的循环体即是所谓的块级作用域,或者更简单一点使用大括号括起来的就叫做块级作用域。块级作用域的最大好处就是不会产生作用域提升,如下所示:~~~js
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1

解构赋值

什么是解构赋值呢?

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

如下所示:

let [a, b, c] = [1, 2, 3];
let [ , , third] = ["foo", "bar", "baz"];
let [x, , y] = [1, 2, 3];
let [head, ...tail] = [1, 2, 3, 4];let [x, y] = [1, 2, 3];

解构赋值还可以设定默认值,我们来看下面的几个例子:

let [foo = true] = [];
foo // truelet [x, y = 'b'] = ['a'];
// x='a', y='b' let [x, y = 'b'] = ['a', undefined];
// x='a', y='b’let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null

如果解构的默认值是一个函数,那么可以触发惰性赋值:

function f() {
console.log('aaa');
} let [x = f()] = [1];

上面的例子中,f函数将不会被执行。

除了结构变量之外,还可以结构对象:

let { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb" let { baz } = { foo: "aaa", bar: "bbb" };
baz // undefinedvar { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa" let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'

解构还支持嵌套的结构:

let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p: [x, { y }] } = obj; x // "Hello"
y // "World"

解构赋值有两个非常重要的作用。

第一就是交换变量:

let x = 1;
let y = 2;
[x, y] = [y, x];

我们就可以不再使用中间变量,直接进行两个变量值的交互。

第二个作用就是从函数中返回多个值:

// 返回一个数组
function example() { return [1, 2, 3]; }
let [a, b, c] = example(); // 返回一个对象
function example() { return { foo: 1, bar: 2 }; }
let { foo, bar } = example();//提取JSON数据
let jsonData = { id: 42, status: "OK", data: [867, 5309] };
let { id, status, data: number } = jsonData;

数组的扩展

ES6中的Array.from方法用于将下面两类对象转为真正的数组:

  • 类似数组的对象(array-like object)
  • 可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。

什么是类似数组对象呢?

所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组。

下面的变量就是类数组变量:

let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 };

这个类数组对象怎么转换成为数组呢?

// ES5的写法
var arr1 = [].slice.call(arrayLike);
// ['a', 'b', 'c']// ES6的写法 let arr2 = Array.from(arrayLike);
// ['a', 'b', 'c']

我们看下通常的使用场景:

// NodeList对象
let ps = document.querySelectorAll('p');
Array.from(ps).forEach(function (p) { console.log(p); }); // arguments对象
function foo() { var args = Array.from(arguments);
// ...
}

什么是可遍历对象呢?

只要是部署了Iterator接口的数据结构,都叫做可遍历对象。

我们看下下面的例子:

Array.from('hello') // ['h', 'e', 'l', 'l', 'o']
let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']

同时还引入了扩展运算符(…),通过扩展运算符,也可以很方便的转换为数组对象:

function foo() { var args = [...arguments]; } // arguments对象
[...document.querySelectorAll('div')] // NodeList对象

Array.from方法还可以接收第二个参数,用来对数组中的元素进行操作:

Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x); Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]

Array.of方法可以很方便的创建新的数组:

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]

函数的扩展

ES6,可以支持函数的默认值了:

function log(x, y = 'World') { console.log(x, y); }
function Point(x = 0, y = 0) { this.x = x; this.y = y; }

函数的默认值可以和解构赋值默认值组合起来使用:

function foo({x, y = 5}) { console.log(x, y); }
foo({}) // undefined, 5
foo({x: 1}) // 1, 5
foo({x: 1, y: 2}) // 1, 2
foo() // TypeError: Cannot read property 'x' of undefined

接下来,我们看一个复杂的例子:

// 写法一
function m1({x = 0, y = 0} = {})
{ return [x, y]; } // 写法二
function m2({x, y} = { x: 0, y: 0 })
{ return [x, y]; }

我们来看一下,上面的两种写法有什么不同呢?

当函数没有参数的情况:

m1() // [0, 0]
m2() // [0, 0]

当x和y都有值的情况:

m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]

当x有值,y无值的情况 :

m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]

当x和y都无值的情况:

m1({}) // [0, 0];
m2({}) // [undefined, undefined]
m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]

看出区别了吗? m1的解构赋值,对于x,y来说是有默认值0的。而m2的解构赋值对于x,y来说是没有默认值的。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/ecmascript-6-startup/

本文来源:flydean的博客

欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

ECMAScript 6新特性简介相关推荐

  1. Oracle11g新特性简介

    转 Oracle 11g 新特性简介https://blog.csdn.net/tianlesoftware/article/details/5134819  Oracle 11g于2007年7月11 ...

  2. JDK8新特性简介、Lambda表达式、Stream流常用api介绍

    JDK8新特性简介.Lambda表达式.Stream流常用api介绍 接口 Java1.8前接口中是不允许有普通方法的,在Java1.8后允许接口中有普通方法,只需要加上default关键字即可: J ...

  3. ECMAScript 2021(ES12)新特性简介

    简介 ES12是ECMA协会在2021年6月发行的一个版本,因为是ECMAScript的第十二个版本,所以也称为ES12. ES12发行到现在已经有一个月了,那么ES12有些什么新特性和不一样的地方呢 ...

  4. ECMAScript 2019(ES10)新特性简介

    简介 ES10是ECMA协会在2019年6月发行的一个版本,因为是ECMAScript的第十个版本,所以也称为ES10. 今天我们讲解一下ES10的新特性. ES10引入了2大特性和4个小的特性,我们 ...

  5. ECMAScript 2016(ES7)新特性简介

    简介 自从ES6(ECMAScript 2015)在2015年发布以来,ECMAScript以每年一个版本的速度持续向前发展.到现在已经是ECMAScript 2020了. 每个版本都有一些新的特性, ...

  6. ECMAScript 2017(ES8)新特性简介

    文章目录 简介 Async函数 共享内存和原子操作 Object的新方法 String的新方法 逗号可以添加到函数的参数列表后面了 简介 ES8是ECMA协会在2017年6月发行的一个版本,因为是EC ...

  7. 即将到来的 ECMAScript 2022 新特性

    大家好,我是若川.持续组织了5个月源码共读活动,感兴趣的可以点此加我微信 ruochuan12 参与,每周大家一起学习200行左右的源码,共同进步.同时极力推荐订阅我写的<学习源码整体架构系列& ...

  8. EcmaScript 6 新特性

    想要完整了学习 ECMAScipt 6,并且能够理解的比较透彻,最好还是首先了解一下 Node.js 和 AJAX 相关知识.可以参考以下博文: Node.js「一」-- Node.js 简介 / N ...

  9. Oracle 11g 新特性简介

    Oracle 11g于2007年7月11日美国东部时间11时(北京时间11日22时)正式发布,11g是甲骨文公司30年来发布的最重要的数据库版本,根据用户的需求实现了信息生命周期管理(Informat ...

最新文章

  1. 执行appium程序时遇到如下报错,ImportError: cannot import name 'InvalidArgumentException',...
  2. 软件测试工程师笔试试题
  3. 高并发资金交易系统设计方案—百亿双十一、微信红包背后的技术架构
  4. jmeter难吗_Jmeter集成Jira提交缺陷
  5. c 语言栈,C语言栈
  6. TF-IDF + K-Means 中文聚类例子 - scala
  7. C#中const和readonly的区别
  8. 理解setState(),异步还是同步?
  9. bzoj 1628 1683: [Usaco2007 Demo]City skyline(模拟)
  10. Android audio切换设备通道流程(二十八)
  11. 22.Linux/Unix 系统编程手册(上) -- 信号:高级特性
  12. es6数组初始化_说一下自己常用的es6的功能
  13. 大数据与机器学习:实践方法与行业案例.1.4 本章小结
  14. phpstrom 设置svn提交的代码同步到服务器
  15. mysql多表in查询_MySQL多表查询
  16. 安卓版 网易云音乐 6.4.3
  17. Macromedia Flash 8 Video Encoder安装
  18. excel 置信区间 计算_正态分布置信区间Excel计算公式.ppt
  19. php引用符号详解——————给变量起小名
  20. hach vue 跳转_Vue路由实现、路由导航、路由模式

热门文章

  1. android actviity模糊,Framework启动过程浅析
  2. python 提取前五行_Pandas 1:如何在Python中载入数据集
  3. DVWA设置mysql_解决DVWA配置报错
  4. STL中map用法详解
  5. live555 源码分析:简介
  6. 如何成为一名大厂的优秀员工?
  7. 狗屎一样的代码如何重构?
  8. 集群管理工具KafkaAdminClient——改造
  9. 面试官:DDD如何指导微服务拆分?90%的程序员都答不上来!
  10. 惊!空 struct 地址竟然不相等