ECMAScript 6(以下简称 ES6)是 JavaScript 语言的标准,ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准
https://npmmirror.com/
https://nodejs.org/download/release/v16.17.1/node-v16.17.1-x64.msi
node -v
npm -v
npm install -g cnpm --registry=https://registry.npmmirror.com
打开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
也可以整个目录一起转换。
将现有对象的属性直接赋值到变量中,在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命令,而且整个语句需要加()。
循环遍历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 = `biying`;
console.log(a);.
即将url字符串变量通过${}的方式嵌入到另一个字符串变量当中。并且字符串的开始和结束需要加上`。
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开始。
使用扩展运算符进行打印
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]);
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的数组。
属性的简洁表示法
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);
即用…扩展运算法打印对象时,不能直接打印,通过扩展运算法给另一个变量赋值后,再打印那个变量。
箭头函数省略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”)。
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);
Promise是异步编程的一种解决方案。Promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript 引擎提供。
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
正在加载
即将resolve和reject函数的给到Image对象,如果图片成功加载就调用resolve,失败就调用reject。将promise对象返回。后面then则是处理执行成功或失败后的结果。将其图片或失败信息添加到div标签中。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);});
但是由于跨域,打印错误信息。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修饰,即等待被修饰的方法执行完毕再往下执行,阻塞。
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实例对象进行调用。
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。