八千字入门ECMAScript 6.0(落灰文章~)

Posted 一只楠喃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八千字入门ECMAScript 6.0(落灰文章~)相关的知识,希望对你有一定的参考价值。

1、ES6基础

1.1什么是ES6

ECMAScript 6.0(以下简称ES6)是javascript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
标准的制定者有计划,以后每年发布一次标准,使用年份作为版本。因为ES6的第一个版本是在2015年发布的,所以又称ECMAScript 2015(简称ES2015)。

版本年份描述
ECMAScript 5.12011年06月
ECMAScript 62015年06月增加的众多内容:let、const、class 等
ECMAScript 72016年06月两个新的功能:求幂运算符(*)和array.prototype.includes方法
ECMAScript 82017年06月并发、原子操作、await/async等等

1.2ES6和JavaScript关系

1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给国际标准化组织ECMA(欧洲计算机制造商协会European Computer Manufacturers Association),希望这种语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版

该标准从一开始就是针对JavaScript语言制定的,但是之所以不叫JavaScript,有两个原因。一是商标,Java是Sun公司的商标,根据授权协议,只有Netscape公司可以合法地使用JavaScript这个名字,且JavaScript本身也已经被Netscape公司注册为商标。二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。

因此,ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现(另外的ECMAScript方言还有Jscript和ActionScript)。日常场合,这两个词是可以互换的

ECMAScript是由ECMA(一个类似W3C的标准组织)参与进行标准化的语法规范。
ECMAScript定义了:

语言语法 – 语法解析规则、关键字、语句、声明、运算符等
类型 – 布尔型、数字、字符串、对象等
原型和继承
内建对象和函数的标准库 – JSON、Math、数组方法、对象自省方法等。

ECMAScript标准不定义html或CSS的相关功能,也不定义类似DOM(文档对象模型)的Web API,这些都在独立的标准中进行定义。ECMAScript涵盖了各种环境中JS的使用场景,无论是浏览器环境还是类似node.js的非浏览器环境

1.3基本语法

1.3.1声明变量

// 定义变量
//1) var 声明普通变量
//2) let 声明局部变量(块级变量)
//3) const 声明常量
var a1 = 1;
let a2 = 2;
const a3 = 3;

  • et 声明局部变量

    • ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
  • const 声明常量
    * const声明一个只读的常量。一旦声明,常量的值就不能改变。
    * 使用const命令声明变量,此变量必须立即初始化,不能留在后面赋值。否则会报错。
    * const的作用域与let命令相同:只在声明所在的块级作用域内有效

1.3.2 模板字符串

  • 模板字符串,用于简化字符串拼凑
//ES5 ,拼凑字符串
var str = "<table>" +
            "<tr>" + 
              "<td>标题</td>" + 
            "</tr>" + 
         "</table";

//ES5 , /换行
var str2 = "<table> \\
            <tr>  \\
                <td>标题</td> \\
            </tr> \\
            </table>";

//ES6
var str3 = `
    <table>
        <tr>
            <td>
            </td>
        </tr>
    </table>
`;
  • 在模板字符串中,可以通过${变量}获取变量的值。
var username = 'jack';
var age = 18;

console.info(`你的姓名是${username} , 你的年龄是${age}`);
  • 创建 demo04_str.js
var username = "jack";

//使用js拼凑一个<table>
var table = "<table>" + 
            "<tr>" + 
            "<td>"+username+"</td>" + 
            "</tr>" +
            "</table>";

//模板字符串
var table2 = `
<table>
<tr>
    <td>${username}</td>
    <td></td>
</tr>
<tr>
    <td></td>
    <td></td>
</tr>
</table>
`;

console.info(table)
console.info(table2)

1.3.3对象简写

  • 简化的对象写法:省略同名的属性值、省略方法的function
let name = "张三";
let age = 18;

let person = {                      //ES5写法
    name : name,
    age : age,
    getAge : function(){
        return this.age;
    }
}

console.info( JSON.stringify(person));
console.info( person.getAge() );

let person2 = {                     //ES6写法
    name,                              //省略同名的属性值
    age,        
    getAge(){                          //省略 function
        return this.age;
    }
}

console.info( JSON.stringify(person2));
console.info( person2.getAge() );

1.3.4箭头函数

  • 箭头函数:用于定义匿名函数的一种简洁写法。(与Java中Lambda表达式极其相似)
//匿名函数
let fn = function(a,b){
    return a + b;
}
console.info( fn(5,10) )    //15

//箭头函数基本语法
let fn2 = (a,b) => {
    return a + b;
}
console.info( fn2(5 , 3) )  //8

//省略1:只有一个参数的情况下,小括号可以省略
// 完整写法
let fn3 = (a) => {
    return a * a;
}
console.info( fn3(5) )      //25

// 省略写法
let fn32 = a => {
    return a * a;
}
console.info( fn32(5) )   //25

//省略2:函数体只有一个条,大括号可以省略。如果是return语句,关键字return必须省略
let fn4 = a => a * a;
console.info( fn4(10) )     //100

// 练习
let fn5 = () => console.info("abc");
fn5();          

let fn6 = (a,b,c) => a+b;
console.info( fn6() )       //NaN (Not a number) 

let fn7 = (a,b,c) => a+b;
fn7(3,4,5)

1.3.5 JS中的循环遍历

  • for循环遍历:普通循环,常用于处理数组(for (let i = 0;i < array.length;i++){})

  • map():数组链式操作函数(array.map( fn ).xxx())

  • forEach() :简化数组、Map、Set的遍历(xxx.forEach( fn ))

  • 准备数据

var arr4 = [‘x’,‘y’,‘z’];

  • map函数的使用

//map函数 , 将数组转换一个新数组
//var 新数组 = 旧数组.map( 处理函数 ); //旧数组中的每一个元素,都将通过“处理函数”进行处理
//实例:将数组 [‘a’,‘b’,‘c’] 转换成字符串 ‘cba’
var m = arr4.map( s => {
return s.toUpperCase();
}).reverse().join(",");
console.info(m);

  • forEach函数的使用

//forEach遍历
arr4.forEach(s => { //遍历数组
console.info(s);
});

2.ES6高级

2.1高级语法

2.1.1变量声明

关键字是否存在变量提升是否存在暂时性死区是否允许重复声明是否允许重新赋值是否允许只声明不赋值
var存在不存在允许允许允许
let不存在存在不允许允许允许
const不存在存在不允许不允许不允许
  • 创建 demo02_var.js
//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


  • 创建 demo02_let.js
    • 注意:依次运行需要代码,其他代码需要使用/**/进行注释,存在运行错误的情况。
//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

  • 创建:demo02_const.js
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

2.1.2解构赋值

  • ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)
  • ES5获得对象数据的语法,如下:
const people = {
    name: 'lux',
    age: 20
}
const name = people.name;				//ES5写法
const age = people.age;
console.log(name + ' ‐‐‐ ' + age)
  • 对象解构:从一个对象一次性解析出多个属性给不同变量
    • 解构的变量名,必须与属性名保持一致。
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

  • 数组解构:按照数组排序依次赋值
// 声明数组
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 (稍后讲解)
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
  • 常见应用:模块内容的提取(稍后讲解)

const { SourceMapConsumer, SourceNode } = require(“source-map”);

2.1.3函数参数名默认值

  • 在声明函数参数时,给参数设置默认值

function log(x, y = ‘World’) { //y参数设置默认值
console.log(x, y);
}
log(‘Hello’) // Hello World
log(‘Hello’, ‘China’) // Hello China
log(‘Hello’, ‘’) // Hello

  • 默认值和解构

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

  • 默认值应用:参数必填

console.info(args);
}
fun2();
fun2(“abc”);

2.1.4箭头函数的this

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

2.1.5Map数据结构(Map集合)

  • JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
  • ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串。
var map = new Map([
    ['k1','v1'],
    ['k2','v2']
]);
//设置数据
map.set('k3','v3');
console.info(map);      //Map { 'k1' => 'v1', 'k2' => 'v2', 'k3' => 'v3' }

map.set(5,"数字key")
console.info(map);      //Map { 'k1' => 'v1', 'k2' => 'v2', 'k3' => 'v3', 5 => '数字key' }

//获得数据
console.info( map.get('k1') );      //v1
console.info( map.get(5) );         //数字key
console.info( map.get('k100') );   //undefined

//判断数据是否存在
console.info( map.has('k2') );      //true

//删除数据
map.delete('k2');
console.info(map);             //Map { 'k1' => 'v1', 'k3' => 'v3', 5 => '数字key' }

//遍历数据
map.forEach( (k,v) => {
    console.info(`键是${k},值是${v}`)
});

2.1.6Set数据结构(Set集合)

  • ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
//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 }

  • 过滤数组中重复的数据
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 ]

2.1.7for…of遍历

  • 在JavaScript中,数据的遍历存在多种,在ES6中提供了for…of ,用于统一所有数据结构的遍历
//准备数据
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遍历
// 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函数的使用
//map函数 , 将数组转换一个新数组  
//var 新数组 = 旧数组.map( 处理函数 );		//旧数组中的每一个元素,都将通过“处理函数”进行处理
//实例:将数组 ['a','b','c'] 转换成字符串 'cba'
var m = arr4.map( s => {
    return s.toUpperCase();
}).reverse().join(",");
console.info(m);

  • forEach函数的使用
//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遍历对象
for(let prop in obj4){
    console.info( prop  + "," + obj4[prop]);
}

2.1.8rest参数(形参…)

  • rest参数,就是JS的可变参数。在形参列表的最后一位变量前,使用“…”
    函数名(参数1, 参数2, …可变)
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);

2.1.9扩展运算符(实参…)

  • 扩展运算符(spread)是三个点(…)。它好比rest参数的逆运算

    • 操作数据是数组,将一个数组转为用逗号分隔的参数序列。
    • 操作数据是对象,取出参数对象的所有可遍历属性,拷贝到当前对象之中
var arr = ['a','b','c'];
function fun3(x,y

以上是关于八千字入门ECMAScript 6.0(落灰文章~)的主要内容,如果未能解决你的问题,请参考以下文章

ECMAScript 6.0 学习笔记

八千字带你高效学通C语言函数(C语言超详细教程)

干货 | ECMAScript 6.0 新特性详解(附视频)

Django(入门终章)长达三万五千字的博文

面渣逆袭:二十二图八千字二十问,彻底弄清MyBatis

面渣逆袭:二十二图八千字二十问,彻底弄清MyBatis