ESMAScript 6.0高级

2023-02-27 09:51:34 浏览数 (1)

目录

1.高级语法

        1.1变量声明

        1.2解构赋值

       1.3函数参数名默认值

        1.4箭头函数的this

        1.5Map数据结构(Map集合)

       1.6Set数据结构(Set集合)

        1.7for...of遍历

        1.8rest参数(形参...)

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

2.模块化

        2.1ES5 CommonJS解决方案

        2.2ES6 module 隐式要求

        2.3ES6 module

        2.4默认导出 export default

1.高级语法

        1.1变量声明

关键字

是否存在 变量提升

是否存在 暂时性死区

是否允许 重复声明

是否允许 重新赋值

是否允许 只声明不赋值

var

存在

不存在

允许

允许

允许

let

不存在

存在

不允许

允许

允许

const

不存在

存在

不允许

不允许

不允许

  • var
代码语言:javascript复制
//1 var 声明的变量,可以提升
{
    var a = 10;
}
console.info(a);    //10

//2 允许重复声明
var b = 20;
var b = 30;
console.info(b);   //30

//3 允许重新赋值
b = 40;
console.info(b);   //40

//4 允许只声明不赋值
var c;
console.info(c);    //undefined
  • let
代码语言:javascript复制
//1 let声明的变量,不允许变量提升
/*
{
    let a = 10;
}
console.info(a);    //异常, a is not defined
*/

//2 存在暂时性死区 : 在块代码中,所有的变量都是局部变量 (必须先声明,再使用)
/*
var b = 10;
{
    console.info(b);        //b is not defined
    let b = 20;
}
*/

//3 不允许重复声明
/*
var c = 10;
let c = 20;     //Identifier 'c' has already been declared  (变量c已经声明了)
*/

/**/
//4 允许重新赋值
let d = 10;
d = 20;
console.info(d);    //20

//5 允许只声明不赋值
let e;
console.info(e);    //undefined
  • const
代码语言:javascript复制
const a = 10;

//1. 不允许提升
/*
{
    const b = 10;
}
console.info(b)     //b is not defined
*/

//2. 存在暂时性死区
/*
var c = 10;
{
    console.info(c)     //c is not defined
    const c = 20;
}
*/

//3. 不允许重复声明
/*
const a = 20;           //Identifier 'a' has already been declared
*/

//4. 不允许重新赋值
/*
a = 20;             //Assignment to constant variable.
*/

//5. 不允许只声明不赋值
//const d;            // Missing initializer in const declaration

        1.2解构赋值

  • ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
  • ES5获得对象数据的语法,如下:
代码语言:javascript复制
const people = {
    name: 'lux',
    age: 20
}
const name = people.name;				//ES5写法
const age = people.age;
console.log(name   ' ‐‐‐ '   age)
  • 对象解构:从一个对象一次性解析出多个属性给不同变量
    • 解构的变量名,必须与属性名保持一致。
代码语言:javascript复制
var person = {
    username : "jack",
    password : "1234",
    "show" : function(){
        console.info("show执行了");
    },
    course : {
        en : 100,
        math : 99
    }
}

//es5获得数据
console.info( person.username )
console.info( person.password )
person.show()

//对象解构
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执行了

//结构对象中的对象
let {course} = person;
console.info(course)    //{ en: 100, math: 99 }
let {course : {en, math}} = person;
console.info(en)        //100
  • 数组解构:按照数组排序依次赋值
代码语言:javascript复制
// 声明数组
var arr = ['江苏','宿迁'];

// 从数组中解构成员
let [province, city] = arr;
console.info(province)
console.info(city)

//交换2个变量
let x = 10;
let y = 20;
console.info(`x = ${x} , y = ${y}`);
[y,x] = [x,y];
console.info(`x = ${x} , y = ${y}`);
  • 常见应用:遍历Map (稍后讲解)
代码语言:javascript复制
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');

for (let [key, value] of map) {
  console.log(key   " is "   value);
}
// first is hello
// second is world
  • 常见应用:模块内容的提取(稍后讲解)
代码语言:javascript复制
const { SourceMapConsumer, SourceNode } = require("source-map");

       1.3函数参数名默认值

  • 在声明函数参数时,给参数设置默认值
代码语言:javascript复制
function log(x, y = 'World') {				//y参数设置默认值
    console.log(x, y);
}

log('Hello') 								// Hello World
log('Hello', 'China') 						// Hello China
log('Hello', '') 							// Hello
  • 默认值和解构
代码语言:javascript复制
function fun1({x = "x1" , y } = {y : "y2"}){
    return [x , y] ;
}
console.info( fun1() );     	 //[ 'x1', 'y2' ]
console.info( fun1({}) );   //[ 'x1', undefined ] ,
							//{} 覆盖 {y:"y2"} ,解构默认值,x=x1,y=undefined
  • 默认值应用:参数必填
代码语言:javascript复制
function fun2(args = new Error("参数必须填写")){
    console.info(args);
}

fun2();
fun2("abc");

        1.4箭头函数的this

  • this对象:
    • function函数中this表示当前对象
    • 箭头函数没有自己的this,箭头函数的this看外层的是否有函数,
      • 如果有,外层函数的this就是内部箭头函数的this,
      • 如果没有,在浏览器环境下this是window;在node.js环境下为指定环境(例如:vue)
  • 创建 demo03_2.js 文件
代码语言:javascript复制
var name="外部";
var user = {
    name : '内部',
    show : function(){
        console.info(this.name)
    },
    show2 : () => {
        console.info(this.name) 
        console.info(user.name)
    }
}

user.show()         //内部
user.show2()        //undefined、内部 
  • 创建 demo03_3.html
代码语言:javascript复制
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
    var name="外部";
    var user = {
        name : '内部',
        show : function(){
            console.info(this.name)
        },
        show2 : () => {
            console.info(this.name)
            console.info(user.name)
        }
    }
    user.show()         //内部
    user.show2()        //外部、内部(在浏览器端,this表示window)
</script>

        1.5Map数据结构(Map集合)

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

       1.6Set数据结构(Set集合)

  • ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
代码语言:javascript复制
//Set集合:存储唯一数据
var set = new Set();
set.add(1);
set.add(2);
set.add(3);
set.add(2);
set.add(1);

console.info( set );        //Set { 1, 2, 3 }
  • 过滤数组中重复的数据
代码语言:javascript复制
var arr = [2, 3, 5, 4, 5, 2, 2];

//方式1
var set2 = new Set();
// 1) 遍历数组,将数据添加到set
arr.map( s => set2.add(s) );
// 2) 遍历set集合,添加到新数组
var arr2 = [];
set2.forEach( v => arr2.push(v) );
console.info( arr2 );       //[ 2, 3, 5, 4 ]

//方式2
var arr3 = [ ... new Set(arr) ]
console.info( arr3 );       //[ 2, 3, 5, 4 ]

        1.7for...of遍历

  • 在JavaScript中,数据的遍历存在多种,在ES6中提供了for…of ,用于统一所有数据结构的遍历。
代码语言:javascript复制
//准备数据
var arr4 = ['x','y','z'];

var map4 = new Map();
map4.set("a","1111");
map4.set("b","2222");
map4.set("c","3333");

var set4 = new Set();
set4.add("m");
set4.add("n");
set4.add("L");

var obj4 = {
    name : "jack",
    password : "1234"
}
  • for…of遍历
代码语言:javascript复制
// for ... of 
for(let a of arr4){           //遍历数组
    console.info(a);
}
for(let [k,v] of map4){      //遍历Map,for…of与解构结合遍历Map
    console.info(`输出的数据键是${k}值是${v}`);
}
for(let s of set4){          //遍历Set
    console.info(s);
}
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,不完善,参考如下:
let obj = {
	//原有内容
	length: 3,
	[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函数的使用
代码语言:javascript复制
//map函数 , 将数组转换一个新数组  
//var 新数组 = 旧数组.map( 处理函数 );		//旧数组中的每一个元素,都将通过“处理函数”进行处理
//实例:将数组 ['a','b','c'] 转换成字符串 'cba'
var m = arr4.map( s => {
    return s.toUpperCase();
}).reverse().join(",");
console.info(m);
  • forEach函数的使用
代码语言:javascript复制
//forEach遍历
arr4.forEach(s => {         //遍历数组
    console.info(s);
});
map4.forEach( (k,v)=> {     //遍历Map
    console.info(`${k} ${v}`);
});
set4.forEach( k => {        //遍历Set
    console.info( k ) ;
});
//obj4.forEach();           //不支持
  • for…in遍历对象
代码语言:javascript复制
for(let prop in obj4){
    console.info( prop    ","   obj4[prop]);
}

        1.8rest参数(形参...)

  • rest参数,就是JS的可变参数。在形参列表的最后一位变量前,使用“...”
代码语言:javascript复制
函数名(参数1, 参数2, …可变)
代码语言:javascript复制
function add(...num){               	//可变参数num,就是一个数组,运行时存放了所有的实参
    var sum = 0 ;
    num.forEach( i => sum  = i);
    return sum;
}
console.info( add(1,2,3) );

function count(args,...other){
    console.info(arguments.length);     //虽有参数的个数,伪数组,不能使用forEach进行遍历
    console.info(other.length);         //可变参数的个数,真数组,可以使用forEach进行遍历
}
count(1,2,3);

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

  • 扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,
    • 操作数据是数组,将一个数组转为用逗号分隔的参数序列。
    • 操作数据是对象,取出参数对象的所有可遍历属性,拷贝到当前对象之中
代码语言:javascript复制
var arr = ['a','b','c'];
function fun3(x,y,z){
    console.info( [x,y,z] );
}

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

let z = { a: 3, b: 4 };
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支持此种思想
  • 模块导出
代码语言:javascript复制
module.exports = (a,b)=> a b;
  • 模块导入
代码语言:javascript复制
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 定义默认输出。一个模块只允许一个默认输出。
  • 默认导出变量

0 人点赞