【ES6】ECMAScript6
1. let声明变量
1.声明变量是不可以重复声明,防止变量被污染
示例代码:
let userName = "张三";
let userName = "李四";
console.log(userName);
2.块级作用域中使用,不可以跳出块级作用域(即不可以提升为全部变量)
块级作用域包含:if else while for switch 等的{ }块级作用域
作用域: 全局作用域,局部(函数)作用域,块级作用域,严格作用域(eval)
示例代码:
for(let i=0;i<1;i++){
let num = i+5;
}
console.log(num)
3.不存在变量提升(即不存在预解析)
示例代码:
console.log(day); //undefined
var day="周五";
console.log(sun); //报错
let sun = "太阳";
4.不影响作用域链
示例代码:
function fn(){
let a = "1";
function aa(){
console.log(a);
}
aa();
}
fn();
2. const声明常量
1.一定要赋初识值
示例代码:
const SCHOOL = "清华大学";
const A ; // 报错
2.一般常量名字大写(行业规范)
3.常量值是不能修改
const SCHOOL = "清华大学";
const SCHOOL = "北京大学";
4.块级作用域
let flag = true;
if(flag){
const SCHOOL = "复旦大学";
}
console.log(SCHOOL);//报错
5.对于数组和对象的元素修改,不算做对常量的修改,不会报错
示例代码:
const arr = ["科比",”勒布朗“,”哈登“];
arr.push("杜兰特");
3.变量解构赋值
ES6中允许按照一定模式从数组和对象中提取值,对变量赋值,称之为解构赋值
1.数组解构
const arr = ["奥迪","奔驰","宝马","五菱"];
let [ao,ben,bao,wuling] = arr;
console.log(ao);
console.log(ben);
console.log(bao);
console.log(wuling);
2.对象解构
const person = {
name:"张三",
age:18,
talk:function(){
console.log("我可以讲好多种语言");
}
}
let {name,age,talk} = person;
4.模板字符串
1.声明
let str = `我是一个字符串`;
2.内容中可以直接出现换行符
let str = `<ul>
<li>周一</li>
<li>周二</li>
</ul>`
3.变量可以直接进行拼接
let mvp = "Kobe";
let mvpString = `${mvp} is my favorite baskterball player !`;
console.log(mvpString);
5.对象的简化写法
ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样写更加简单。
示例代码:
let name = "徐福";
let change = "我们改变了世界";
let fn = function(){
console.log("我是世界第一");
}
const person = {
name,
change,
fn,
talk(){
console.log("我创造了某个国家的文明");
}
}
6.箭头函数
ES6允许使用箭头定义函数
1.箭头函数的声明和调用
let fn = function(a,b){}
let fn = (a,b)=>{
return a+b;
}
console.log(fn(1,2));
2.箭头函数与ES5声明的函数的区别
this是静态的,始终指向函数声明时所在的作用域下的this的值
示例代码:
window.name = "张三";
function getName(){
console.log(this.name);
}
let fn = ()=>{
console.log(this.name);
}
// getName();
// fn();
let obj ={
name:"李四"
}
getName.call(obj);
fn.call(obj);
3.不可以作为构造函数去实例化对象
4.不能使用arguments对象
5.箭头函数的简写
1.省略小括号,当形参有且只有一个的时候
let add = (n)=>{ return n++; };
let add = n => {return n++;};
2.省略花括号,当代码体有且只有一行的时候,此时return也必须去掉,而且语句的执行结果就是函数的返回值
let add = (n)=>{ return n++; };
let add = n => n++;
6.箭头函数的适用范围
适合用于与this无关的回调,定时器,数组方法的回调
不适合用于与this有关的回调,事件回调,对象方法
示例代码:
obj.addEventListener("click",function(){
console.log(this);
})
const arr = [1,2,3,4,5,6,7,8,9,10];
const result = arr.filter(function(item){
if(item%2==0){
return true;
}else{
return false;
}
})
const arr = [1,2,3,4,5,6,7,8,9,10];
const result = arr.filter(()=>{
if(item%2==0){
return true;
}else{
return false;
}
})
7.函数的默认值
ES6允许给函数参数赋值初始值
1.形参初始值,具有默认值的参数,一般位置靠后(行业规范)
示例代码:
function add(a,b,c=10){
return a+b+c;
}
add(1,2);//13
2.与解构赋值结合
function person({name,age}){
console.log(`${name}是一个${age}的老人`);
}
let per1 = {name:"张三",age:80};
person(per1);
8.rest参数
1.ES6引入rest参数,用于获取函数的多余参数,rest参数之后不能再有其他参数(即只能是最后一个参数)
arguments对象的获取
function fn(){
console.log(arguments);
}
fn("中山","佛山","珠海");
function fn(...args){
console.log(args);
//可以使用数组的方法
}
fn("中山","佛山","珠海");
2.rest参数必须放在最后,rest参数之后不能再有其他参数(即只能是最后一个参数)
function fn(a,b,...args){
console.log(args);
}
fn("中山","佛山","珠海","深圳","广州");
9.扩展运算符
…扩展运算符能将数组转换为逗号分隔的参数序列
示例代码:
let arr = ["a","b","c"];
function fn(){
console.log(arguments);
}
fn(...arr);
1.数组的拼接
let arr1 = ["a","b"];
let arr2 = ["c","d"];
let newArr = [...arr1,...arr2];
2.数组的克隆
let arr1 = ["a","b"];
let arr2 = [...arr1];
3.将伪数组转换为真数组
let divs = document.querySelectorAll("div");
let divArr = [...divs];
10.Symbol基本使用
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,它是javascript语言的第七种数据类型,是一种类似于字符串的数据类型。
特点:
- Symbol的值是唯一的,用来解决命名冲突问题
- Symbol的值不能 与其他数据进行运算,
- Symbol定义的对象属性不能使用for…in循环 遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名。
声明Symbol
let s = Symbol();
console.log(s,typeof(s));
let s1 = Symbol("秋老虎");
let s2 = Symbol("秋老虎");
console.log(s1==s2);//false
let s3 = Symbol.for("张三");
let s4 = Symbol.for("张三");
console.log(s3 == s4); //true
示例代码:
let game = {
up:function(){console.log(“我在起飞”)},
down:function(){console.log("我在降落")}
}
let methods = {
up:Symbol(),
down:Symbol()
}
game[methods.up] = function(){
console.log("我长翅膀了");
}
game[methods.down] = function(){
console.log("我认怂");
}
Object.getOwnPropertySymbols(game);
//返回一个给定对象自身的所有 Symbol 属性的数组。
game[Object.getOwnPropertySymbols(game)[0]]();
Reflect.ownKeys(obj)
//返回一个数组,其值表示所提供对象的属性的键
//Obj:它是从中获取自己的 key 的目标对象。
game[Reflect.ownKeys(game)[2]]();
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场 景下自动执行。
属性 | 描述 |
---|---|
Symbol.hasInstance | 当其他对象使用 instanceof 运算符,判断是否为该对 象的实例时,会调用这个方法 |
Symbol.isConcatSpreadable | 对象的 Symbol.isConcatSpreadable 属性等于的是一个 布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展开 |
Symbol.species | 创建衍生对象时,会使用该属性 |
Symbol.match | 当执行 str.match(myObject) 时,如果该属性存在,会 调用它,返回该方法的返回值。 |
Symbol.replace | 当该对象被 str.replace(myObject)方法调用时,会返回 该方法的返回值。 |
Symbol.search | 当该对象被 str. search (myObject)方法调用时,会返回 该方法的返回值。 |
Symbol.split | 当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值。 |
Symbol.iterator | 对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器 |
Symbol.toPrimitive | 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。 |
Symbol. toStringTag | 在该对象上面调用 toString 方法时,返回该方法的返回值 |
Symbol. unscopables | 该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。 |
示例代码:
const arr = [1,2,3];
const arr1 = [4,5,6];
arr1[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr1));
11.迭代器
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提 供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
- ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费
- 原生具备 iterator 接口的数据(可用 for of 遍历)
- Array:数组
- Arguments :伪数组
- Set:是一个特殊的类型集合,伪数组
- Map:是一个带键的数据项的集合,伪数组
- String:字符串
- TypedArray :实质是一种特殊的包含数值类型的数组,定型数组
- NodeList:节点
-
工作原理
1.创建一个指针对象,指向当前数据结构的起始位置
2.第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
3.接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
4.每调用 next 方法返回一个包含 value 和 done 属性的对象
示例代码:
let person = {
name:"张三",
status:[
"科比",
"姚明",
"詹姆斯"
],
[Symbol.iterator]: function(){
let index = 0;
let _this = this;
return {
next:function(){
if(index<_this.status.length){
const result = {
value:_this.status[index],
done:false
}
index++;
return result;
}else{
return {
value:undefined,
done:true
}
}
}
}
}
}
for(let v of person){
console.log(v);
}
12.Promise
Promise 是 ES6 引入的异步编程的新解决方案。
语法上 Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。
- Promise 构造函数: Promise (excutor) {}
- Promise.prototype.then 方法
- Promise.prototype.catch 方法
示例代码:
const p = new Promise(function(resolve,reject){
setTimeout(function(){
let succ = "读取成功";
resolve(succ);
let err = "读取失败";
reject(err);
})
})
p.then(function(value){
console.log(value);
},function(reason){
console.log(reason);
})
promise封装ajax,示例代码
const p = new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest();
xhr.open("GET","http://www.liulongbin.top:3006/api/getbooks");
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){//判断状态
if(xhr.status == 200){//判断响应状态码
// console.log(xhr.response);
resolve(xhr.response);
}else{
// console.error(xhr.status);
reject(xhr.status);
}
}
}
})
p.then(function(value){
console.log(value);
},function(error){
console.log(error)
})
then,调用then方法时,返回的结果是Promise对象,对象状态由回调函数的执行结果决定
1.如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值为对象成功的值
示例代码:
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("成功了!");
// reject("失败了!");
},1000)
})
const result = p.then( value=>{
console.log(value);
return "123";
}, reason =>{
console.log(reason);
})
console.log(result);
2.如果回调函数中返回的结果是promise对象,回调函数的结果由内部promise对象的resolve或者reject决定
示例代码
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("成功了!");
// reject("失败了!");
},1000)
})
const result = p.then( value=>{
console.log(value);
return new Promise((resolve,reject)=>{
reject("失败了!!!!");
})
}, reason =>{
console.log(reason);
})
console.log(result);
可以进行链式调用:
p.then(value=>{
console.log(value);
}).then(value=>{
console.log(value);
})
catch:用来指定promise失败的回调函数
示例代码:
const p = new Promise((resolve,reject)=>{
// resolve("成功了");
reject("失败了");
})
p.then(value=>{
console.log(value)
}).catch(error=>{
console.log(error)
})
13.模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
1.模块化的好处
-
防止命名冲突
-
代码复用
-
高维护性
2.模块化规范产品
ES6 之前的模块化规范有:
- CommonJS => NodeJS、Browserify
- AMD => requireJS
- CMD => seaJS
3.ES6 模块化语法
模块功能主要由两个命令构成:export 和 import。
⚫ import 命令用于输入其他模块提供的功能
通用的导入方式
import * as m1 from './js/module.js';
解构赋值形式
import {city,location} from './js/module.js';
import {city as chengshi ,location as address} from './js/module.js'
import {default as m2} from './js/module.js';
简便形式,针对于默认暴露
import m3 from './js/module.js'
⚫ export 命令用于规定模块的对外接口
示例代码:
<script type="module">
import * as m1 from './js/mode.js';
</script>
分别暴露
export let city="中山市";
export function location(){
console.log("我坐落在美丽的广东省");
}
统一暴露
let city = "中山市";
function location(){
console.log("我坐落在美丽的广东省");
}
export {city , location}
默认暴露:
export default {
city:"中山市",
location(){
console.log("我坐落在美丽的广东省");
}
}
14.class类
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对 象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是 一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象 原型的写法更加清晰、更像面向对象编程的语法而已。
类:是一个抽象的概念
对象:是类的实例化
知识点:
-
class 声明类
-
constructor 定义构造函数初始化
class Shoujie { constructor(price,branch){ this.price = price; this.branch = branch; } call(){ console.log(`${this.price}:${this.branch}`); } } let huawei = new Phone(2859,"华为"); huawei.call();
-
static 定义静态方法和属性
class Shouji { static name = "手机"; static change(){ console.log("可以改变 世界"); } constructor(price,branch){ this.price = price; this.branch = branch; } call(){ console.log(`${this.price}:${this.branch}`); } }
-
extends 继承父类
-
super 调用父级构造方法
-
父类方法可以重写
function Phone(price,branch){ this.price = price; this.branch = branch; } Phone.prototype = { call:function(){ console.log(`${this.price}:${this.branch}`); } } function SmartPhone(price,branch,color,size){ Phone.call(this,price,branch); this.color = color; this.size = size; } SmartPhone.prototype = new Phone(); SmartPhone.prototype.photo = function(){ console.log("我可以拍照"); } let sp = new SmartPhone(2999,"小米","black","5.5inch"); sp.call(); sp.photo();
class Shouji { static name = "手机"; constructor(price,branch){ this.price = price; this.branch = branch; } call(){ console.log(`${this.price}:${this.branch}`); } } class xiaoshouji extends Shouji { constructor(price,branch,color,size){ super(price,branch); this.color = color; this.size = size; } photo(){ console.log("我可以拍照"); } playGame(){ console.log("我可以打游戏"); } call(){ console.log("我可以视频通话"); } } let huawei = new xiaoshouji(2999,"华为","red","5.5inch"); console.log(huawei); huawei.playGame(); huawei.call(); huawei.photo();
15.数值扩展
1.Number.EPSILON 是javascript表示最小精度
EPSILON属性的值接近于 2.2204460492503130808472633361861E-16
示例代码:
console.log(0.1+0.2 == 0.3);//false;
function equal(a,b){
if(Math.abs(a-b)<Number.EPSILON){
return true;
}else{
return false;
}
}
equal(0.1+0.2,0.3);
2.二进制和八进制
let b = 0b1010; //10
let o = 0o777; //511
let d = 100;
let f = 0xff; // 255
3.Number.isFinite();检测一个数值是否为有限数
Number.isFinite(Infinity); //true
4.Number.isNaN();检测一个数是否为NaN
Number.isNaN("a");//true
5.Number.parseInt();将字符串转换为整数
Number.parseInt("5555abc");//5555
6.Number.parseFloat();将字符串转换为浮点数
Number.parseInt("555.5abc");//555.5
7.Number.isInteger()判断一个数是否为整数
Number.isInteger(12.3);//false;
8.Math.trunc将数字的小数部分抹掉
console.log(Math.trunc(2.5));//2
9.Math.sign();判断一个数到为正数,负数,还是0
Math.sign(100);//1
Math.sign(0);//0
Math.sign(-100);//-1
16.对象的扩展方法
1.Object.is() 判断两个值是否完全相等
console.log(Object.is(120,120));// ===
console.log(Object.is(NaN,NaN));// ===
2.Object.assign()对象的合并
const obj1 = {
name:"张三",
age:18,
sex:"男"
}
const obj2 = {
name:"李四",
age:18,
}
Object.assign(obj1,obj2);
3.Object.setPrototypeOf设置原型对象 Object.getPrototypeOf 获取原型对象
const school ={
name:"清华大学"
}
const citys = {
xiaoqu:["北京","上海","深圳"]
}
Object.setPrototypeOf(school,citys);
Object.getPrototypeOf(school);
17.集合
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯 一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进 行遍历,集合的属性和方法:
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回 boolean 值
- has 检测集合中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
let s = new Set();
//创建一个非空集合
let s1 = new Set([1,2,3,1,2,3]);
//集合属性与方法
//返回集合的元素个数
console.log(s1.size);
//添加新元素
console.log(s1.add(4));
//删除元素
console.log(s1.delete(1));
//检测是否存在某个值
console.log(s1.has(2));
//清空集合
console.log(s1.clear());
18.Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。Map 的属 性和方法:
- size 返回 Map 的元素个数
- set 增加一个新元素,返回当前 Map
- get 返回键名对象的键值
- has 检测 Map 中是否包含某个元素,返回 boolean 值
- clear 清空集合,返回 undefined
//创建一个空 map
let m = new Map();
//创建一个非空 map
let m2 = new Map([
['name','张三'],
['slogon','我是个大人物']
]);
//属性和方法
//获取映射元素的个数
console.log(m2.size);
//添加映射值
console.log(m2.set('age', 6)); //获取映射值
console.log(m2.get('age'));
//检测是否有该映射
console.log(m2.has('age'));
//清除
console.log(m2.clear());