ESMAScript 6.0高级

69 阅读6分钟

目录


1.高级语法

        1.1变量声明

关键字

是否存在

变量提升

是否存在

暂时性死区

是否允许

重复声明

是否允许

重新赋值

是否允许

声明不赋值

var

存在

不存在

允许

允许

允许

let

不存在

存在

不允许

允许

允许

const

不存在

存在

不允许

不允许

不允许

  • var
console.info(c);    //undefined
  • let
console.info(a);    //异常, a is not defined

//2 存在暂时性死区 : 在块代码中,所有的变量都是局部变量 (必须先声明,再使用)

    console.info(b);        //b is not defined

let c = 20;     //Identifier 'c' has already been declared  (变量c已经声明了)

console.info(e);    //undefined
  • const
console.info(b)     //b is not defined

    console.info(c)     //c is not defined

const a = 20;           //Identifier 'a' has already been declared

a = 20;             //Assignment to constant variable.

//const d;            // Missing initializer in const declaration

        1.2解构赋值

  • ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
  • ES5获得对象数据的语法,如下:
const name = people.name;				//ES5写法

console.log(name + ' ‐‐‐ ' + age)
  • 对象解构:从一个对象一次性解析出多个属性给不同变量
    • 解构的变量名,必须与属性名保持一致。
        console.info("show执行了");

console.info( person.username )

console.info( person.password )

let {username,password,show, age } = person;

console.info(username)      //jack

console.info(password)      //1234

console.info( show )        //[Function: show]

console.info( age )         //undefined

show();                     //show执行了

console.info(course)    //{ en: 100, math: 99 }

let {course : {en, math}} = person;

console.info(en)        //100
  • 数组解构:按照数组排序依次赋值
let [province, city] = arr;

console.info(`x = ${x} , y = ${y}`);

console.info(`x = ${x} , y = ${y}`);
  • 常见应用:遍历Map (稍后讲解)
map.set('first', 'hello');

map.set('second', 'world');

for (let [key, value] of map) {

  console.log(key + " is " + value);
  • 常见应用:模块内容的提取(稍后讲解)
const { SourceMapConsumer, SourceNode } = require("source-map");

       1.3函数参数名默认值

  • 在声明函数参数时,给参数设置默认值
function log(x, y = 'World') {				//y参数设置默认值

log('Hello') 								// Hello World

log('Hello', 'China') 						// Hello China

log('Hello', '') 							// Hello
  • 默认值和解构
function fun1({x = "x1" , y } = {y : "y2"}){

console.info( fun1() );     	 //[ 'x1', 'y2' ]

console.info( fun1({}) );   //[ 'x1', undefined ] ,

							//{} 覆盖 {y:"y2"} ,解构默认值,x=x1,y=undefined
  • 默认值应用:参数必填
function fun2(args = new Error("参数必须填写")){

        1.4箭头函数的this

  • this对象:
    • function函数中this表示当前对象
    • 箭头函数没有自己的this,箭头函数的this看外层的是否有函数,
      • 如果有,外层函数的this就是内部箭头函数的this,
      • 如果没有,在浏览器环境下this是window;在node.js环境下为指定环境(例如:vue)
  • 创建 demo03_2.js 文件
        console.info(this.name)

        console.info(this.name) 

        console.info(user.name)

user.show2()        //undefined、内部 
  • 创建 demo03_3.html
    <meta charset="UTF-8">

    <title>Document</title>

        show : function(){

            console.info(this.name)

            console.info(this.name)

            console.info(user.name)

    user.show()         //内部

    user.show2()        //外部、内部(在浏览器端,this表示window)

        1.5Map数据结构(Map集合)

  • JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
  • ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串。 

       1.6Set数据结构(Set集合)

  • ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
console.info( set );        //Set { 1, 2, 3 }
  • 过滤数组中重复的数据
var arr = [2, 3, 5, 4, 5, 2, 2];

arr.map( s => set2.add(s) );

set2.forEach( v => arr2.push(v) );

console.info( arr2 );       //[ 2, 3, 5, 4 ]

var arr3 = [ ... new Set(arr) ]

console.info( arr3 );       //[ 2, 3, 5, 4 ]

        1.7for...of遍历

  • 在JavaScript中,数据的遍历存在多种,在ES6中提供了for…of ,用于统一所有数据结构的遍历。
var arr4 = ['x','y','z'];
  • for…of遍历
for(let a of arr4){           //遍历数组

for(let [k,v] of map4){      //遍历Map,for…of与解构结合遍历Map

    console.info(`输出的数据键是${k}值是${v}`);

for(let s of set4){          //遍历Set

for(let key of Object.keys(obj4)){   	//自定义对象不能遍历,需要借助keys转换成“键数组”

    console.info(`对象的键是${key},值是${obj4[key]}`);

for(let [k,v] of Object.entries(obj4)){//也可以借助entries转换成“键值对”

    console.info(`entries : 对象的键是${k},值是${v}`);

//补充:自定义对象通过特殊处理([Symbol.iterator])也可以遍历,但存在bug,不完善,参考如下:

	[Symbol.iterator]: Array.prototype[Symbol.iterator]
  • JS中已有的遍历

遍历方式

描述

实例

for循环遍历

普通循环,常用于处理数组

for (let i = 0;i < array.length;i++){

map()

数组链式操作函数

array.map( fn ).xxx()

forEach()

简化数组、Map、Set的遍历

xxx.forEach( fn )

for…in

任意顺序遍历一个对象的可枚举属性

for(let xx in obj) {}

for…of

不同的数据结构提供统一的访问机制

for(let xx of obj) {}

  • map函数的使用
//var 新数组 = 旧数组.map( 处理函数 );		//旧数组中的每一个元素,都将通过“处理函数”进行处理

//实例:将数组 ['a','b','c'] 转换成字符串 'cba'

    return s.toUpperCase();
  • forEach函数的使用
arr4.forEach(s => {         //遍历数组

map4.forEach( (k,v)=> {     //遍历Map

    console.info(`${k} ${v}`);

set4.forEach( k => {        //遍历Set

//obj4.forEach();           //不支持
  • for…in遍历对象
    console.info( prop  + "," + obj4[prop]);

        1.8rest参数(形参...)

  • rest参数,就是JS的可变参数。在形参列表的最后一位变量前,使用“...”
函数名(参数1, 参数2, …可变)

function add(...num){ //可变参数num,就是一个数组,运行时存放了所有的实参

num.forEach( i => sum += i);

console.info( add(1,2,3) );

function count(args,...other){

console.info(arguments.length);     //虽有参数的个数,伪数组,不能使用forEach进行遍历

console.info(other.length);         //可变参数的个数,真数组,可以使用forEach进行遍历

        1.9扩展运算符(实参...)
-----------------------

*   扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,
    *   操作数据是数组,将一个数组转为用逗号分隔的参数序列。
    *   操作数据是对象,取出参数对象的所有可遍历属性,拷贝到当前对象之中

console.info( [x,y,z] );

fun3( arr ); //[ [ 'a', 'b', 'c' ], undefined, undefined ]

fun3( ...arr ); //[ 'a', 'b', 'c' ]

let n = { ...z }; // { a: 3, b: 4 }


2.模块化
=====

*   在ES6之前,JavaScript一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。
*   在ES6之前,社区提供了一些解决方案,最主要两种:CommonJS和AMD

        2.1ES5 CommonJS解决方案
---------------------------

*   CommonJS一个服务器端的解决方案(commonsJs可以在node.js运行)
*   CommonJS 需要一个兼容的脚本加载器,来支持require 和 module.exports 函数,用于模块导入导出。
*   Node.js支持此种思想
*   模块导出

module.exports = (a,b)=> a+b;


*   模块导入

let add = require("./demo07_1");

console.info( add(1,2) );


        2.2ES6 module 隐式要求
--------------------------

*   ES6的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。
*   严格模式主要有以下限制。

> 变量必须声明后再使用
> 
> 函数的参数不能有同名属性,否则报错
> 
> 不能使用with语句
> 
> 不能对只读属性赋值,否则报错
> 
> 不能使用前缀0表示八进制数,否则报错
> 
> 不能删除不可删除的属性,否则报错
> 
> 不能删除变量delete prop,会报错,只能删除属性delete global\[prop\]
> 
> eval不会在它的外层作用域引入变量
> 
> eval和arguments不能被重新赋值
> 
> arguments不会自动反映函数参数的变化
> 
> 不能使用arguments.callee
> 
> 不能使用arguments.caller
> 
> 禁止this指向全局对象
> 
> 不能使用fn.caller和fn.arguments获取函数调用的堆栈
> 
> 增加了保留字(比如protected、static和interface)

        2.3ES6 module
---------------------

*   一个模块,就是一个对其他模块暴露自己的属性或者方法的文件。
    *   ES6 模块主要由两个命令构成:export和import。
    *   export命令:规定模块的对外接口。一条export语句声明一次,一个文件中可有多条。
    *   import命令:导入其他模块。

        2.4默认导出 export default
------------------------------

*   使用import命令加载模块,必须知道模块中的的变量名或函数名,否则无法加载。
*   为了方便使用模块,模块允许使用export default 定义默认输出。一个模块只允许一个默认输出。
*   默认导出变量

> 本文使用 [文章同步助手](https://juejin.cn/post/6940875049587097631) 同步