文章目录
一、安装Nodejs环境
ECMAScript 6(以下简称 ES6)是 JavaScript 语言的标准,ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准
1、安装Nodejs环境
- 阿里的npm镜像地址:
https://npmmirror.com/
- 下载Nodejs:
https://nodejs.org/download/release/v16.17.1/node-v16.17.1-x64.msi
一直点next即可。 - 安装完成后,win+r输入cmd打开命令行,查看是否安装成功:
node -v
在命令行中查看npm是否也安装成功:npm -v
- 安装cnpm镜像:
npm install -g cnpm --registry=https://registry.npmmirror.com
- 在安装Nodejs的同时,会附带一个npm命令,npm 是Node的包管理工具,npm 的简单结构有助于 Node.js 生态系统的激增,现在 npm 仓库托管了超过1百万个可以自由使用的开源库包。
2、安装Babel转码器
-
打开vscode工具,选择打开文件夹,选择自己创建的空文件夹,然后在工具栏那里选择查看→终端,在终端中使用npm指令安装Babel:
npm install --save-dev @babel/core
-
安装presets字段设定转码规则:
npm install --save-dev @babel/preset-env
-
在项目的根目录下创建配置文件babelrc,并将presets规则加入到该配置文件,代码如下:
{ "presets": [ "@babel/env" ], "plugins": [] }
-
安装Babel命令行转码工具:
npm install --save-dev @babel/cli
-
创建es6Demo.js,添加如下ES6代码
input.map(item => item + 1);
-
将es6Demo.js内的代码转换成ES5存入es5Demo.js中:
npx babel es6Demo.js -o es5Demo.js
也可以整个目录一起转换。
二、ES6新特性(一)
1、Let命令
- var关键字是函数级作用域,关键字let是块级作用域。即var的作用域在函数中,而let的作用域在块中。
- let不存在变量提升,即只能在声明后使用;而var可以先使用再声明。
- let不允许在一个块作用域内重复声明同一个变量,或者let在前var在后声明同一个变量也不可以(var就可以)。
2、Const命令
- const声明一个只读的变量。即一旦声明,该变量的值就不可改变(相当于常量)。也就是说同时也必须得立即初始化,不能留到后面再赋值。
- const的作用域与let相同,都是块级作用域,只在声明所在的块级作用域内有效。
- const声明的常量也是跟let一样不存在提升,即先声明后使用。
- const声明的常量也是跟let一样不可重复声明。
3、对象解构赋值
-
将现有对象的属性直接赋值到变量中,在script标签中,添加如下代码
var user = {name:"zzx",age:21} const {name,age} = user; const {log} = console; log(name,age);
即将user对象解构到name和age中,直接使用name和age,而不用使用user.name。但是变量名必须与属性名相同,才能取到正确的值。
-
对象的解构赋值可以很方便地将现有对象的方法,赋值到某个变量。
const {log} = console; log(name,age); const {abs,ceil,floor,random} = Math; log(random())
即直接将Math对象的方法赋值到变量中,只是通过变量名调用方法。直接使用random(),而不是Math.random()。
-
使用let命令声明的变量名,同时后面还有跟解构赋值时使用的变量名相同,此时解构赋值时的变量不能加let命令,而且整个语句需要加()。
4、字符串扩展
-
循环遍历for of
var s = "lufei"; for(let i of s){ console.log(i) }
即不用s[i]打印字符,可以使用i打印字符。
-
模板字符串(template string)是增强版的字符串,用反引号`标识。它可以作为普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
let url = "https://www.bing.com"; let a = `<a href="${url}">biying</a>`; console.log(a);.
即将url字符串变量通过${}的方式嵌入到另一个字符串变量当中。并且字符串的开始和结束需要加上`。
5、 字符串新增扩展
-
includes():返回布尔值,表示是否找到了参数字符串
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部let s = "lu fei"; console.log(s.includes("u f")); console.log(s.startsWith("l")); console.log(s.endsWith("i"));
这三个方法都支持第二个参数,表示开始搜索的位置
let s = "lu fei"; console.log(s.includes("f",2)); console.log(s.startsWith("f",3)); console.log(s.endsWith("e",5));
这3个方法的第二个参数,也就是从0开始到该下标作为该字符串或者从该下标开始到字符串结束位置作为该字符串(不包含该下标对应的值)。
-
repeat(x):将原字符串重复x次,然后赋值给一个新的字符串并返回。
let s = "lu fei"; console.log(s.repeat(3));
-
ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全,返回一个新字符串。
padStart():用于在头部补全。
padEnd():用于在尾部补全。let s = "lu fei"; console.log(s.padStart(8,"x")); console.log(s.padEnd(8,"x"));
即将字符串s用字符x补全到8个字符。
-
trimStart()和 trimEnd()与trim()方法的行为一致。
trimStart()消除字符串头部的空格
trimEnd()消除尾部的空格let str = " haizeiwang "; console.log(str.trimStart()); console.log(str.trimEnd());
-
at():接收一个整数作为参数,返回参数指定下标位置的字符,支持负索引(即倒数)。
let s = "lu fei"; console.log(s.at(0)); console.log(s.at(-1));
即从后往前的下标从-1开始,从前往后的下标从0开始。
三、ES6新特性(二)
1、扩展运算符(…)
-
使用扩展运算符进行打印
var arr = [10,20,30]; console.log(...arr);
-
使用扩展运算符将数组作为参数打印最大值max
var arr = [10,20,30]; console.log(Math.max(...arr));
-
合并数组
var arr = [10,20,30]; var arr2 = [30,20,10]; console.log([...arr,...arr2]);
2、数组的新增方法
-
arguments伪数组转换为真数组
function add(){ let collect = Array.from(arguments); collect.push(40); console.log(collect); } add(10,20,30);
-
元素集合伪数组转换为真数组
let h3s = document.querySelectorAll('h3'); console.log(Array.from(h3s));
在body标签内script标签外增加h3标签。
-
对象伪数组转换为真数组
var user = { "0" : "zzx", "1" : 20, "2" : "男", length : 3 } console.log(Array.from(user));
-
将一组数值转换成数组
console.log(Array.of(10,20,30));
Array(10)的话则是开辟一个空间为10的数组。
3、对象内的简洁表示法
-
属性的简洁表示法
let name = "zzx"; const user = { name, age:21 } console.log(user.name);
-
方法的简洁表示法
let name = "zzx"; const user = { name, age:21, getName(){ console.log(this.name); } } user.getName();
即方法不需要写:function
-
返回值的简洁表示法
function getPoint() { const x = 11; const y = 22; return {x, y}; } console.log(getPoint())
-
属性名表达式,即在方括号内用表达式作为对象的属性名。
let propKey = 'zzx'; let obj = { [propKey]: true, ['a' + 'bc']: 123 }; console.log(obj)
即可以在对象内通过[表达式]的形式动态定义属性名。
-
对象的扩展运算符
let z = { a: 1, b: 2 }; let n = { ...z }; console.log(n);
即用…扩展运算法打印对象时,不能直接打印,通过扩展运算法给另一个变量赋值后,再打印那个变量。
4、箭头函数
-
箭头函数省略function关键字,并且当语句等于一条时,可以省略大括号
var add = (x,y) => x+y; console.log(add(4,5))
-
箭头函数使代码简洁(匿名函数)
var arr = [10,20,30] arr.map(item =>{ console.log(item); })
-
对于普通函数来说,内部的this指向函数运行时所在的对象。
而箭头函数没有自己的this对象,内部的this就是定义时上层作用域中的this。var name = "slong"; var user = { name:"lfei", getName(){ setTimeout(() =>{ console.log(this.name); }) } } user.getName()
即对于普通函数而言,this.name指向的是外层的name,也就是"slong";
而箭头函数没有this,此时this指的是箭头函数外面一层的this,也就是getName()方法那层的name(“lfei”)。
5、Set的使用
-
Set中成员的值都是唯一的,没有重复的值。即去重。
const s = new Set(); let arr = [1, 2, 3, 4, 5, 5, 2]; arr.forEach(x => s.add(x)); for (let i of s) { console.log(i); }
-
Set函数可以接受一个数组作为参数
let arr = [1, 2, 3, 4, 5, 5, 2]; const s = new Set(arr); for (let i of s) { console.log(i); }
-
字符串去重
console.log([...new Set("abababc")].join(""));
-
使用Set的add()方法加入值时,不会发生类型转换
var set = new Set(); set.add("8") set.add(8) console.log(set);
即整数8和字符串8并不会产生去重。
-
size属性,即打印set的长度。
var set = new Set(); set.add(8) console.log(set.size);
-
delete()方法,根据值删除,返回boolean值
var set = new Set(); set.add(8) console.log(set.delete(8));
-
has()方法,根据值判断是否存在,返回boolean值
var set = new Set(); set.add(8) console.log(set.has(8));
-
clear()方法,清空set
var set = new Set(); set.add(8) set.add(9) set.clear() console.log(set.size);
四、ES6新特性(三)
1、promise对象
Promise是异步编程的一种解决方案。Promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript 引擎提供。
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
- promise加载图片资源
即将resolve和reject函数的给到Image对象,如果图片成功加载就调用resolve,失败就调用reject。将promise对象返回。后面then则是处理执行成功或失败后的结果。将其图片或失败信息添加到div标签中。<div id="myid">正在加载</div> <script> var image = document.getElementById("myid"); function loadImageAsync(url){ const promise = new Promise(function(resolve,reject){ //异步处理:消耗时间的代码 const image = new Image(); image.src = url; image.onload = function(){ resolve(image) } image.onerror = function(){ reject(new Error("Could not load image at"+url)) } }) return promise; } const promise = loadImageAsync("https://www.baidu.com/img/pcdoodle_2a77789e1a67227122be09c5be16fe46.png") promise.then(function(data){ console.log(data); image.append(data) },function(error){ image.html(error) console.log(error) }) </script>
2、Promise对象封装Ajax
- Promise对象封装Ajax发送网络请求
但是由于跨域,打印错误信息。const getJSON = function (url) { const promise = new Promise(function (resolve, reject) { const handler = function () { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; const client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); }); return promise; }; getJSON("https://www.bing.com").then(function (json) { console.log(json); }, function (error) { console.error('出错了', error); });
3、Async函数
Async函数可以将异步操作变为同步操作,并且使异步操作更加方便。
-
使用async函数和await修饰方法,从而实现同步
function timeout(ms) { return new Promise((resolve) => { setTimeout(function(){ console.log("OK") resolve(); }, ms) }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value); } asyncPrint("OK2", 500);
即使用async函数修饰方法,并且在该方法下用async函数的await修饰定时器方法,从而实现先执行完定时器再执行打印。await修饰,即等待被修饰的方法执行完毕再往下执行,阻塞。
4、Class的使用
-
Class的基本使用
class Person{ constructor(name,age){ this.name = name; this.age = age; } getName(){ console.log(this.name); } } let person = new Person("zzx","18"); person.getName()
即通过class来定义类,与Java的class类似。并且不存在提升,即先声明后使用。
-
通过类实例对象调用方法
class People{ say(){ console.log("what fuck"); } } var p = new People(); p.say()
-
类的实例对象可调用的属性
class Person{ constructor(name,age){ this.name = name; this.age = age; } getName(){ console.log(this.name); } } let person = new Person("zzx","18"); getName(); console.log(person.name,person.age);
-
静态方法,类相当于实例的原型,所有在类中定义的方法,都会被实例(new)继承。
在方法前加上static关键字,表示该方法不会被实例继承,不能通过实例调用,而是要通过类来调用。class Person { static classMethod() { console.log("Hello"); } } Person.classMethod() var p = new Person(); p.classMethod()
-
静态属性,即通过类调用的属性。
class People{} People.age = "18" console.log(People.age);
-
Class的继承(extends)
class Person{ constructor(name,age){ this.name = name; this.age = age; } getName(){ console.log(this.name); } static getInfo(){ console.log("父类") } } class Student extends Person{ constructor(name,age,schoolName){ super(name,age); this.schoolName = schoolName; } getSchool(){ console.log(this.schoolName); } } let student= new Student("zzx",18,"dongruan"); student.getName(); Student.getInfo(); student.getSchool();
即Student类继承Person类,Student类在构造方法中必须先通过父类的构造方法完成塑造,得到与父类同样的实例属性和方法,然后再对其加工,添加自己的实例属性和方法。因为Student类继承Person类,Person类的getName方法没有加static关键字,所以可以直接调用,但是getInfo方法加了static,所以不能通过student实例对象进行调用。
5、Module的语法
-
JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。这对开发大型的、复杂的项目形成了巨大障碍。
通过export命令显式指定输出的代码;通过import命令输入。 -
使用Nodejs方式测试Module语法
nodejs采用的是CommonJS的模块化规范,使用require引入模块;而import是ES6的模块化规范,想要使用import,必须引入babel转义支持,通过babel进行编译,使其成为node的模块化代码。 -
在终端进入到文件夹中,全局安装babel-cli:
npm install -g babel-cli
-
安装 babel-preset-env:
npm install -D babel-preset-env
-
在根目录下创建a.js,添加export输出代码
export var A = "A"
-
在index.js中,添加import输入
import { A } from "./a.js" console.log(A);
此时如果需要输入多个变量,则需要在大括号中用,将变量隔开;需要给变量改名,则需要在前面加上as。
-
运行测试:
babel-node --presets env index.js
此时index.js的大括号中的属性名需要与a.js中的属性名相同。如果不添加export和import,则会报错,因为Nodejs中文件与文件之间具有隔离性。 -
用*指定一个对象,所有输出值都加载到这个对象上。
1)将a.js修改如下export var A = "11" export var B = "22" export function add(){ console.log("A+B="+(A+B)) }
2)将Index.js修改如下
import * as algorithm from "./a.js" algorithm.add() console.log(algorithm.A,algorithm.B);
即在import输入时,使用*将a.js的属性和方法都加载到algorithm对象中,通过algorithm对象来调用。
-
export default命令,指的是在指定输出代码的前面加入,可以不设置方法名或变量名。然后在import输入时,可以任意取名且可以不加大括号,不需要加as关键字。但是一个js文件中只允许存在一个export default。
总结
- 1)安装Nodejs环境,会带有npm命令,但是npm镜像是国外的,安装国内的cnpm,但好像现在cnpm安装完成后,要用npm指令。即指令还是npm,但是此时的镜像已经改成国内的镜像。
2)创建VUE项目时,直接在VSCODE中打开一个新文件夹,在文件夹内可以在创建文件夹,然后在准备放项目的文件夹中直接打开终端,进入到文件夹中,通过cnpm指令直接创建VUE项目。
Babel的作用是ES6代码转换成ES5,实现向下兼容。 - 1)let和const命令,都是不存在提升、不可重复声明、块级作用域。但是使用const声明后不可改变它的值。
2)对象解构赋值,即可以将对象中的属性和方法,直接赋值给变量。但是此时变量名必须与对象中的属性名或方法名相同。可以很方便取出属性或方法,而不用通过对象去获取。
3)includes()、startsWith()、endsWith()这三个方法是判断字符串是否存在,都是返回布尔值。
后面这些字符串方法,都是返回一个新的字符串对象。
at()接收一个整数下标参数,搜索字符串。
padStart()、padEnd()用来补全字符串。
repeat()接收一个整数,用来将原字符串进行整数次复制。
trimStart()、trimEnd()用来去掉空格字符。 - 1 Array.from()是将伪数组转换成真数组。
Array.of()是将一组数值转换成数组。
2)()=>{},箭头函数没有自己的this,它是引用外一层的this。箭头函数可以使代码更简洁,并且在语句等于1条时,可以省略大括号。
3)Set对象有去重的作用,并且有add()、delete()、has()、clear()方法,以及size属性。
add(),添加值到Set对象中。
delete(),从Set对象删除对应的值,返回布尔值。
has(),即判断该值是否存在,返回布尔值。
clear(),即清空Set对象。
size属性,即Set对象的长度。 - 1)Promise是异步编程的一种解决方案。promise可以接收2个参数resolve和reject函数分别来处理成功和失败的操作。将promise对象返回。调用该promise对象的then方法对成功或失败的结果进行处理操作。
2)Promise对象封装Ajax发送网络请求的异步操作。使用XMLHttpRequest对象发送网络请求,并使用一个函数来处理resovle和reject函数;最后将promise对象返回。然后调用promise对象的then方法处理成功或失败的响应信息。
3)Async函数可以将异步操作变为同步操作,并且使异步操作更加方便。使用Async和await在异步中实现同步。即外层方法被Async修改,内层被await修饰时,执行到被await修饰的方法时,会被阻塞等待该方法执行完再往下执行。 - Class类,与java的class类似,也可以通过extends关键字继承。
1)通过static修饰的方法,不能通过实例对象进行调用。
2)静态属性,即类本身的属性。也就是说通过 类.属性(静态属性赋值)的方式去赋值时,new出来的类的实例对象是无法调用到该静态属性的。
3)Student类在构造方法中必须先通过父类的构造方法完成塑造,得到与父类同样的实例属性和方法,然后再对其加工,添加自己的实例属性和方法。如果子类在构造方法中没有调用super方法,则子类得不到自己的this对象同时会报错。 - Module语法,主要有export、import、export default。在Nodejs中采用CommonJS的模块化规范,使用require引入模块。而import是ES6的模块化规范关键字。需要使用babel进行转义。export显式指定一个输出的代码,import显示指定输入的代码,export default是显示指定一个输出代码的另一种形式,变量或方法可以不命名,但是每个js只允许存在一个,此时import接收时可以任意取名并且可以不加{}。
在import中,as关键字可以为引入的变量重命名。
在 as 变量名 前面加上*可以让引入的js文件中所有export修饰的方法或变量加载到该变量,并且不用加{}。