ES6~ES11笔记

一、ES6


1.1.let变量声名以及声名特性

1.声明的变量不能重复声明

2.块级作用域(全局,函数,eval);

{
	let girl = '***'
}

只在代码块里有效。

3.不存在变量提升

不允许在定义变量前调用变量

console.log(song)
var song = '***'
----underfine
console.log(song)
let song = '***'
----报错

4.不影响作用域链

1.2.const 声明常量以及特点

1.一定要赋初始值,不然控制台会报错

2.一般常量使用大写(潜规则)

3.常量的值不能修改

const fff = '$$$'
fff = '%%%'
----报错

4.块级作用域

{
	const play = '^^^'
}
console.log(play)
---underfine

5.对于数组和对象的元素的修改,不算对常量的修改,不会报错。因为用const定义数组和对象,常量名只是保存了它们的地址(指针),const定义的引用数据类型,保存的事地址,地址本身不能修改,但是它所指的那片堆内存是可以改变的。

1.3.模板字符串

1.ES6引入新的声字符串的方式 [``]

2.内容中可以直接出现换行符。

3.变量拼接

let fff = '某某某'
let ddd = '${fff}水泥地发射点'
console.log(ddd)
---'某某某水泥地发射点'
1.4.解构赋值

ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,者被称为解构赋值。解构同名属性就是获取那个同名属性,自定义变量名就按顺序解构赋值。数组是按顺序赋值的,对象是按变量名赋值的。

1.数组的结构

const F4 = ['11','22','33'];
let [one,two,three];
console.log(one)
console.log(two)
console.log(three)
----
11
22
33
----

2.对象的解构

const zhao = {
    name:'赵',
    age:'不知',
    xiaoping: function(){
		console.log("我可以")
    }
}

let {name,age,xiaopin} = zhao;
console.log(name);
...
xiaoping();

let {xiaopin} = zhao
xiaopin() // 不用再前面加一个zhao.
1.5.对象的简化写法

ES6允许再大括号里面,直接写入变量和函数,作为对象的属性和方法。

这样的书写更加简洁。

let name = '##';
let change = function(){
    console.log('^^&&&%')
}

const school = {
    name:name,
    change:change,
    improve:function(){
        console.log("33445566")
    }
}
-----简化后
const school = {
    name,
    change,
    improve(){
        console.log("33445566")
    }
} 
1.6.箭头函数以及声明特点(重点)

ES6 允许使用[箭头] (=>) 定义函数

声明一个函数

let fn = (a,b) => {
	return a + b;
}

1.this 是静态的,this 始终指向函数声明时所在作用域下的this的值(无论用声明方法去调用箭头函数,箭头函数所指向的值都是不变的)。

function getName(){
	console.log(this.name)
}
function getName2 = () => {
	console.log(this.name)
}
// 设置 window 对象的 name 属性
window.name = '111';
const school = {
    name:"222"
}

// 直接调用
getName(); // 111
getName2(); // 111

//call 方法调用,call 方法是可以改变函数方法里面的this的指向。
getName(school);// 222
getName2(school);// 111

2.不能作为构造实例化对象

let Person = (name,age) => {
	this.name = name;
	this.age = age;
}
let me = new Person('xiao',20)
console.log(me)
---控制台上会报错

3.不能使用 argument 变量(argument用于存放函数的所有形参)

let fn = () => {
	console.log(argument)
}
fn(1,2,3)
---控制台上会报错

4.箭头函数的简写

(1)省略小括号,当形参有且只有一个的时候

let add = n => {
	return n + n;
}
console.log(add(9));
--- 18

(2)省略花括号,当代码体只有一条语句的时候,此时 return 必须省略(还可以省略小括号),而且语句的执行结果就是函数的返回值

let pow = n => n*n;
console.log(pow(9))
---81
1.7.箭头函数总结

看箭头函数外层是否有函数,如果有,则外层函数的this就是箭头函数的this。如果没有,则this就是window。

普通函数

const arr = [1,6,9,10,100,25]
const result = arr.filter(function(){
	if(item % 2 === 0)
		return true
	else{
		return false
	}
});

箭头函数

const result = arr.filter(item => item % 2 === 0)
console.log(result)

箭头函数适合与 this 无关的回调,如定时器,数组的方法问题;

箭头函数不适合与 this 有关的回调,如DOM元素的事件回调,对象的方法;

{
	name:'###',
    getName() => {
        this.name;
    }
}

btn.addEventListener("click",function(){
    //此时普通函数的this指向事件源
    //如果使用箭头函数,事件源将变成外部作用域的this值,即这个函数所在的作用域
})

扩展:就是对象中的箭头函数的 this 永远和最外层的对象所处的环境的this保持一致,不论套了多少层。

1.8.函数参数的默认值设置

ES6允许给函数参数赋值初始化值

1.形参初始值 具有默认值的参数,一般位置要靠后(潜规则)

function add(a,b,c=10){
	return a + b + c
}
let result = add(1,2);
let result2 = add(1,2,3);
console.log(result)
console.log(result2)
----13
----6

2.与解构赋值结合

function connect({host="127.0.01",username,password,port}{
	console.log(host)	
	console.log(username)
	console.log(password)
	console.log(port)
})
// 往里面传一个对象实参
connect({
	host:'ftpp.com',
	username:'root',
	password:'root',
	port:3306
})

当你传了实参的值就用实参的值,若没有传递实参的值,就默认用形参的值。

1.9.rest参数

ES6引入rest参数,用于获取函数的实参,用来代替 arguments

ES5获取实参的方法

function data(){
console.log(arguments);
}
data('11','22','33');

res参数(rest参数必须要放到参数后面)

function data(...arges){
	console.log(arges);
}
data('11','22','33');


const obj1={
    q:'zzl'
}
const obj2={
    s:'wxl'
}
const data={...obj1,...obj2}; //相当于合并了两个对象
console.log(data);//{q:'zzl',s:'wxl'}
1.10.扩展运算符

[…] 扩展运算符能将 [数组] 转换为逗号分隔的 [参数序列]

const school =['赵','张','王']
function ch(){
	console.log(arguments)
}
ch(...school) // 相当于 ch('赵','张','王')
ch(school) //相当于 ch(school)
1.11.扩展运算符的运用

1.数组的合并

const K = ['11','22'];
const M = ['33','44'];
const L = [...K,...M]
console.log(L)
---11,22,33,44

2.数组的克隆

const A = ['E','G','M']
const B = [...A]; // ['E','G','M']

数组的克隆:若是有引用数据类型的话,也是浅拷贝。深拷贝会另外创造一个一模一样的对象,新对象跟原来对象不共享内存,修改新对象不会改到原对象。

3.将伪数组转为真正的数组

const divs = document.querySelectorAll('div')
// divs是一个对象
const divArr = [...divs]
console.log(aivArr);//现在是一个数组
1.12.Symbol

ES6引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。

Symbol特点:

  • Symbol的值是唯一的,用来解决命名冲突的问题

  • Symbol值不能与其他数据进行运算

  • Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用

  • Reflect.ownKeys来获取对象的所有键名

1.创建Symbol

//1.
let s = Symbol()
let S1 = Symbol()
let S2 = Symbol()
console.log(S1 === S2)
// false

//2.Symbol.for创建
let S3 = Symbol.for('11')
let S4 = Symbol.for('22')
console.log(S3 === S4)
// true

2.不能与其他数据进行运算

let result = s + 100
let result = s > 100
let result = s + s
// 以上的结果再控制台上都会报错

Symbol.for:该方法会根据给定的键 key ,来从运行时的 symbol 注册表中找到对应的 symbol ,如果找到了,则返回它,否则,新建一个与该键关联的 symbol ,并放入全局 symbol 注册表中。

js中的八大数据类型:

u underfined
s string   symbol
o object
n null    number
b boolean
1.13.对象添加Symbol类型的属性

1.给对象添加方法方式一:

let game = {name:'ran'};
//声明一个对象
let game = {
    up:Symbol();
    down:Symbol()
};
game[method.up] = function(){
	console.log("$$$")
}
game[method.down] = function(){
	console.log("%%%")
}
// 用 Symbol 添加的属性不会与game中相同属性名的属性冲突

2.给对象添加方法方式二:

let youxi = {
	name:'狼人杀',
	[Symbol('say')]:function(){
		console.log("我可以发言")
	},
	[Symbol('zibao')]:function(){
		console.log("我可以自爆")
	},
}
// 最后在对象youxi外部调用:youxi[say]()这样就可以调用“我可以发言”那个方法了,调用:先在对象外定义变量`let say = Symbol('say')`,在把对象youxi内部中括号的Symbol('say')替换成刚刚在外面定义的变量say,即[say]:function

总结:为了防止你创建的方法和之前已经创建的对象本身的方法冲突,选择在另一个对象中用symbol创建独一无二的方法,用[]调用,不会污染本身对象中的方法。

Symbol值作为对象属性名时,不能用点运算符,哎对象内部,使用 Symbol 值定义属性时,Symbol值必须放在方括号之中。

Symbol()在添加一个属性给一个方法时,不会和方法中现有的属性名冲突,更好添加属性。

1.14.迭代器的应用-自定义遍历数据

1.迭代器(lterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。

2.原理:

(1)创建一个指针对象,指向数据结构的起始位置;

(2)第一次调用==next()==方法,指针自动指向数据结构第一个成员;

(3)接下来不断调用next(),指针一直往后移动,直到指向最后一个成员;

(4)每次调用next()就返回一个包含value和done属性的对象

手写迭代器,应用:

const banjin = {
	name:'尼古拉斯凯奇',
	stus:[
		'xsz',
		'dfc',
		'sfd',
		'sdf',
	],
    //自己给某些结构加上iterator接口
	[Symbol.iterator](){
		// 索引遍历
		let index = 0;
		// 存放btn的this
		let _this = this;
		return {//返回一个指针对象,即创建一个指针对象
			next:function(){//创建对象的next方法
				if(index < _this.stus.length){
					const result = {vaule:_this.stus[index],done:false};
					//下标自增
					index++;
					//返回结果
					return result
				}else{
				return {value:undefined,done:true};
				}
			}
		}
	}
}
for(let v of banjin){
    console.log(v);
}

由于自己定义的对象无法用 for of 来遍历,所以要自己手动添加迭代器。

数组的常用方法:

forEach

缺点:找到目标还会继续循环,并且不受return和break的影响。

some

找到目标后,可以通过return结束循环。

const arr=[]

arr.some((item,index)=>{
  if(item=='zzl'){
	console.log(item)
    return true
  }
})

every

只要每一项都满足every里面的判断条件,则最终返回true。

const arr=[
  {id:1,state:true},
  {id:2,state:true}
]
//判断数组中的所有state是否都为true
const result=arr.every(item=>item.state)

filter

const data=arr.filter(item=>item.state)

filter会把满足条件的数据重新过滤到的新数组中,不满足的通通过滤掉。

reduce

arr.filter(item=>item.state).reduce(累加的结果,当前循环项)=>{ },初始值)

第一次循环累加的结果默认等于初始值,以后循环累加的结果等于上一次累加的结果加上循环项里的数据。

const arr=[{id:1,state:true,price:10}]

let sum=0

arr.filter(item=> item.state).reduce((sum,item)=>{
    return sum += item.price
    //return给下一次累加使用
},0)
1.15.生成器函数声明与调用

生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同,是一种特殊的函数

异步编程,纯回调函数 node,fs,ajax,mongdb

yield是函数代码的分隔符:

function * gen(){
    
	yield '一只';
    
	yield '二只';
    
	yield '三只';
}
let iterator = gen()
console.log(iterator.next()) //{value:"一只",done:false} 执行第一段,并且返回yield后面的值。
console.log(iterator.next())//{value:"二只",done:false}
console.log(iterator.next())//{value:"三只",done:false}
console.log(iterator.next())//{value:"underfined",done:true}

for(let v of gen()){
    console.log(v)
}
//一只,二只,三只

iterator刚开始指向gen函数的地址,而yield又把函数分成了若干个节点,iterator通过next可以依次访问各个节点。

1.16.生成器函数的传递参数
function * gen(arg){
    console.log(arg)
	let one = yield 111;
    console.log(one)
	let two = yield 222;
    console.log(two)
	let three = yield 333;
    console.log(three)
}
//执行获取迭代器对象
let iterator = gen('AAA')
console.log(iterator.next())
//next方法可以传入实参
console.log(iterator.next('BBB'))
console.log(iterator.next('CCC'))
console.log(iterator.next('DDD'))
//AAA --- arg
//{value:111,done:false}
//BBB --- one
//{value:222,done:false}
//CCC --- two
//{value:333,done:false}
//DDD --- three
//{value:"underfined",done:true}

在next里传递参数进去,则是传给当前yield的上一个yield的值

1.17.生成器实例(重点)

异步编程:文件操作,网络操(Ajax,request)数据库操作

1.要求:过一秒输出111,过两秒输出222,过三秒输出333,

使用传统计时器:

setTimeout(()=>{
		console.log(111);
		setTimeout(()=>{
            console.log(222);
            setTimeout(()=>{
                console.log(333);
            },3000)
        },2000)
	},1000)

这样就会形成回调地狱。

使用生成器函数,解决回调地狱问题。

function one(){
	setTimeout(()=>{
		console.log(111);
	},1000)
}
function two(){
	setTimeout(()=>{
		console.log(222);
	},2000)
}
function three(){
	setTimeout(()=>{
		console.log(333);
	},3000)
}

function * gen(){
    yield one;
    yield two;
    yield three;
}

//调用生成器函数
let iterator = gen();
iterator.next();

2.模拟异步获取用户数据,再获取订单数据,再获取对应的商品数据

function getUsers(){
	setTime(()=>{
		let data = "用户数据";
        // 调用next方法,并且将数据传入
        iterator.next(data);
	},1000)
};
function getGoods(){
	setTime(()=>{
		let data = "订单数据";
        iterator.next(data);
	},1000)
};
function getOrder(){
	setTime(()=>{
		let data = "商品数据";
        iterator.next(data);
	},1000)
};

function * gen(){
	let users = yield getUsers;
    console.lod(users)
    let goods = yield getGoods;
    console.lod(goods)
    let order = yield getOrder;
    console.lod(order)
}

// 调用生成器函数
let iterator = gen()
//启动生成器函数
iterator.next()

与同步有些相似,实际上还是异步操作

1.18.Promise

Promise是ES6引入的异步编程的新解决方案。语法上 Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

1.基本特性:

<script>
    const p =new Promise((resolve, reject)=>{
        setTimeout(()=>{
            let data='数据库数据'
            // resolve(data);
            reject(data);
        })
    })

    p.then(function (value){         //成功则执行第一个回调函数,失败则执行第二个
        console.log(value)
    },function (reason){
        console.error(reason)
    })
</script>

2.Promise.then()方法

<script>
    const p =new Promise((resolve, reject) =>{
        setTimeout(()=>{
            resolve('用户数据');
        })
    });

//then()函数返回的实际也是一个Promise对象
//1.当回调后,返回的是非Promise类型的属性时,状态为fulfilled,then()函数的返回值为对象的成功值,如reutnr 123,返回的Promise对象值为123,如果没有返回值,是undefined

//2.当回调后,返回的是Promise类型的对象时,then()函数的返回值为这个Promise对象的状态值

//3.当回调后,如果抛出的异常,则then()函数的返回值状态也是rejected
    let result = p.then(value => {
        console.log(value)
        // return 123;
        // return new Promise((resolve, reject) => {
        //     resolve('ok')
        // })
        throw 123
    },reason => {
        console.log(reason)
    })
    console.log(result);
</script>

3.Promise.catch()方法

//catch() 函数只有一个回调函数,意味着如果 Promise 对象状态为失败就会调用 catch() 方法并且调用回调函数

<script>
    const p = new Promise((resolve, reject) => {
        setTimeout(()=>{
            reject('出错啦')
        },1000)
    })

    p.catch(reason => {
        console.log(reason)
    })
</script>
1.19.Promise封装Ajax的请求
 function sendAjax(url) {
            return new Promise((resolve, reject) => {
                //  1.创建对象
                const xhr = new XMLHttpRequest();
                xhr.responseType = 'json';
                // 2.初始化设置请求方法(类型)和url
                xhr.open("GET", "https://api.apiopen.top/getJoke", true);
                // 3.发送
                xhr.send();
                // 4.绑定事件,onreadystatechange,存储函数(或函数名)处理响应结果(每当 readyState 改变时,就会触发 onreadystatechange 事件,一共会触发 4 次,从 0 到 4)
                // readyState 属性存有 XMLHttpRequest 的状态信息
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status < 300) {
                            resolve(xhr.response);
                        } else {
                            reject(xhr.status);
                        }
                    }
                }
            })
        }
        sendAjax()
            .then(value => {
                console.log(value);
                // console.log(sendAjax());
            }, reason => {
                console.warn(reason);
            })
1.20.Promise.then()方法
<script>
    const p =new Promise((resolve, reject) =>{
        setTimeout(()=>{
            resolve('用户数据');
        })
    });

//then()函数返回的实际也是一个Promise对象
//1.当回调后,返回的是非Promise类型的属性时,状态为fulfilled,then()函数的返回值为对象的成功值,如reutnr 123,返回的Promise对象值为123,如果没有返回值,是undefined

//2.当回调后,返回的是Promise类型的对象时,then()函数的返回值为这个Promise对象的状态值

//3.当回调后,如果抛出的异常,则then()函数的返回值状态也是rejected
    let result = p.then(value => {
        console.log(value)
        // return 123;
        // return new Promise((resolve, reject) => {
        //     resolve('ok')
        // })
        throw 123
    },reason => {
        console.log(reason)
    })
    console.log(result);
</script>

1.21.Promise实践练习-多个文件内容读取

使用传统的函数嵌套会造成回调地狱

使用promise实现

const p = new Promise((resolve,reject) => {
	fs.readFile("./文件夹/文件1.md",(err,data) => {
		resolve(data);
	});
});

// 可以使用Promise链来实现,而且p.then()返回的也是一个Promise类型的值
p.then(value => {
	return new Promise(((resolve,reject) => {
        fs.readFile("./文件夹/文件2.md",(err,data) => {
            //以数组的形式传递给下一个then
		resolve([value,data]);
	});
  })
}).then(value => {
        return new Promise((resolve,reject) => {
            fs.readFile("./文件夹/文件3.md",(err,data) => {
                value.push(data)
                resolve(value)
            })
      })
}).then(value => {
        console.log(value)
})
1.22.Promise.catch()方法
//catch()函数只有一个回调函数,意味着如果Promise对象状态为失败就会调用catch()方法并且调用回调函数
<script>
    const p = new Promise((resolve, reject) => {
        setTimeout(()=>{
            reject('出错啦')
        },1000)
    })

    p.catch(reason => {
        console.log(reason)
    })
</script>

2.1.Set

ES6提供了新的数据结构set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用[扩展运算符]和[ for…of…]进行遍历,集合的属性和方法(还可以数组去重):

  • size返回集合的元素个数

  • add增加一个新元素,返回当前集合

  • delete删除元素,返回boolean值has检测集合中是否包含某个元素,返回boolean值

<script>
    let s = new Set();
    let s2 = new Set(['A','B','C','D'])

    //元素个数
    console.log(s2.size);

    //添加新的元素
    s2.add('E');

    //删除元素
    s2.delete('A')

    //检测集合中是否存在要检测的元素
    console.log(s2.has('C'));

    //清空
    s2.clear()

    console.log(s2);
</script>

2.2.集合实践
<script>
    let arr = [1,2,3,4,5,4,3,2,1]

    //1.数组去重
    let result = [...new Set(arr)]
    console.log(result);
    //2.交集
    let arr2=[4,5,6,5,6]
    let result2 = [...new Set(arr)].filter(item => new Set(arr2).has(item))
    console.log(result2);
    //3.并集
    let result3=[new Set([...arr,...arr2])]
    console.log(result3);
    //4.差集
    let result4= [...new Set(arr)].filter(item => !(new Set(arr2).has(item)))
    console.log(result4);

</script>

2.3.Map

ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用『扩展运算符』和「for…of…』进行遍历。Map的属性和方法。

<script>
    let m = new Map();
    m.set('name','ran');
    m.set('change',()=>{
        console.log('改变!')
    })
    let key={
        school:'atguigu'
    }
    m.set(key,['成都','西安']);

    //size
    console.log(m.size);

    //删除
    m.delete('name');

    //获取
    console.log(m.get('change'));

    // //清空
    // m.clear()

    //遍历
    for(let v of m){
        console.log(v);
    }
</script>

3.1.Class

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

<script>
    class shouji {
        // constructor是构造方法,名字不能修改
        constructor(brand,price) {
            this.brand=brand;
            this.price=price
        }
		//方法必须使用该语法,不能使用 ES5 的对象完整形式
        call(){
            console.log('我可以打电话')
        }
    }

	//实例化对象
    let A = new shouji('1+',1999);
    console.log(A)
</script>

3.2.Class的静态成员
<script>
  class Person{
      static name='手机'
  }
  let nokia = new Person();
  console.log(nokia.name);
</script>

3.3.构造函数继承

javascript的继承主要是依托其 原型与原型链的概念来实现的。

  • 构造函数:用来初始化新对象的函数叫做构造函数。如示例中的Cat函数就是构造函数
  • 实例对象:通过 new 关键字创建出来的对象。如3.2中的Person就是实例对象
  • 原型对象及prototype:构造函数有一个 prototype 属性,它指向实例对象的原型。常使用原型对象来实现继承
  • constructor:原型对象具有constructor属性,指向原型对象的构造函数
  • proto:__proto__属性类似是指针,指向构造函数原型对象
  • prototype__proto__的区别,简单理解为: 构造函数.prototype === 实例对象.__proto__,他们都指向同一个原型对象。

原型链JavaScript 对象(除了 null)在创建的时候就会关联一个对象,这个对象就是原型,每一个对象都会从原型上继承属性,原型也是对象,所以原型也有原型对象,层层往上,直到 Object.prototype,这就是原型链。

<script>
  function Phone(brand,price){
      this.brand=brand;
      this.price=price;
  }
  Phone.prototype.call=function (){
      console.log("我可以打电话");
  }
  function SmartPhone(brand,price,color,size){
      Phone.call(this,brand,price);
      this.color=color;
      this.size=size;
  }

  //设置子级构造函数原型
  SmartPhone.prototype=new Phone;
  SmartPhone.prototype.constructor=SmartPhone;

  //声明子类方法
  SmartPhone.prototype.photo = function (){
      console.log('我可以玩游戏');
  }
  const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch')
  console.log(chuizi);
</script>

3.4.Class的类继承

定义一个子类,来继承一个父类,子类通过super传递参数,来调用父类的构造函数,来进行初始化子类构造方法中一些与父类构造方法中同名的变量,也可以说super === 父类的constructor

<script>
    class Phone{
        constructor(brand,price) {
            this.brand=brand;
            this.price=price;

        }
        //父类的成员属性
        call(){
            console.log('我可以打电话')
        }
    }

    class SmartPhone extends Phone{
        constructor(brand,price,color,size) {
            //通过super传递参数,来调用父类的构造函数,(super === Phone.constructor)来做初始化
            super(brand,price);
            this.color=color;
            this.size=size;
        }
        // 以下是子类独有的方法
        photo(){
            console.log('拍照');
        }

        playGame(){
            console.log('打游戏');
        }
    }
    const xiaomi=new SmartPhone('小米',1999,'黑色','4.7inch')
    xiaomi.call();
    xiaomi.photo();
    xiaomi.playGame();
</script>

3.5.子类对父类方法的重写

子类对父类中的方法重写覆盖。

<script>
    class Phone{
        constructor(brand,price) {
            this.brand=brand;
            this.price=price;

        }
        //父类的成员属性
        call(){
            console.log('我可以打电话')
        }
    }
    class SmartPhone extends Phone{
        constructor(brand,price,color,size) {
            super(brand,price);
            this.color=color;
            this.size=size;
        }
        photo(){
            console.log('拍照');
        }

        playGame(){
            console.log('打游戏');
        }

        //重写!!内容会将父类中的同名方法中的内容覆盖掉
        //但在子类显示原型的隐形原型里面,原有的方法还存在。
        call(){
            console.log('我可以进行视频通话')
        }
    }
    const xiaomi=new SmartPhone('小米',1999,'黑色','4.7inch')
    xiaomi.call();
    xiaomi.photo();
    xiaomi.playGame();
</script>

3.6.getset的设置
<script>
  class Phone{
      get price(){
          console.log("价格被读取了")
          return 'I LOVE YOU'
      }

      set price(val){
          console.log('价格被修改了')
          return val;
      }
  }

    //实例化对象
    let s = new Phone();
    s.price=12  
    // console.log(s.price)   //其实是调用price方法
</script>

3.6.数值扩展
<script>
   // Number.EPSILON是 JavaScript的最小精度,属性的值接近于 2.22044...E-16
   function equal(a,b){
       if(Math.abs(a-b) < Number.EPSILON){
           return true;
       }else {
           return false;
       }
   }

   console.log(equal(0.1 + 0.2 === 0.3))  //false
   console.log(equal(0.1+0.2,0.3))  //true

   //二进制和八进制
   let b = 0b1010; //2进制
   let o = 0o777;  //8进制
   let d = 100;    //10进制
   let x = 0xff;   //16进制
   console.log(x)   //255

   //检测一个数是否为有限数
   console.log(Number.isFinite(100));  //true
   console.log(Number.isFinite(100/0));  //false
   console.log(Number.isFinite(Infinity));  //false

   //检测一个数值是否为NaN
   console.log(Number.isNaN(123))  //false

   //字符串转整数
   console.log(Number.parseInt('5213123love')); //5213123
   console.log(Number.parseFloat('5.123123神器')); //5.123123

   //判断是否为整数
   console.log(Number.isInteger(5));  //true
   console.log(Number.isInteger(2.5)); //false
   
   //将小数部分抹除
   console.log(Math.trunc(3.45345345345)) //3

   //检测一个数到底是正数、负数、还是0
   console.log(Math.sign(100)) //1
   console.log(Math.sign(0))  //0
   console.log(Math.sign(-123)) //-1
</script>

3.7.对象方法扩展
<script>
    //1.Object.is 判断两个值是否完全相等
    console.log(Object.is(120,120))  //true
	console.log(Object.is(NaN,NaN))  //false

    //2.Object.assign 对象的合并
    const a = {
        name:'ran',
        age:12
    }
    const b = {
        pass:'i love you'
    }
    console.log(Object.assign(a,b))   //{name:'ran',age:'12',pass:'i love you'}

    //3.Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
    const school = {
        name:'尚硅谷'
    }
    const cities = {
        xiaoqu:['北京','上海']
    }
    Object.setPrototypeOf(school,cities)
    console.log(Object.getPrototypeOf(school))  //{xiaoqu: Array(2)}
    console.log(school)  //{name: "尚硅谷"}
</script>

4.1.模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

模块化的好处:

  • 防止命名冲突
  • 代码复用
  • 高维护性
  • 模块化规范产品

ES6之前的模块化规范有:

  • CommonJS ====> NodeJS、Browserify
  • AMD ====> requireJS
  • CMD ====> seaJS

语法:

模块功能主要有两个命令构成:export和import

export命令用于规定模块的对外接口
import命令用于输入其他模块提供的功能

浏览器使用ES6的模块化方式一

1.通用的导入方式

m1.js文件(分别暴露)

export let school = '尚硅谷'
export function teach(){
    console.log('教技能')
}

m2.js文件(统一暴露)

let school = 'ATSDFG'
function teach1(){
	console.log("%%")
}
export {school,teach}

m3.js文件(默认暴露)

export default {
	school:'ATSDFG',
	change:function (){
		console.log("&&&")
	}
}
<script type="module">
    import * as m1 from "./src/js/m1.js";
	import * as m2 from "./src/js/m2.js";
	import * as m3 from "./src/js/m3.js";
	console.log(m1);
</script>

2.解构解析

<script type="module">
    import {school,teach} from "./src/js/m1.js";
	import {school as gui,teach1} from "./src/js/m2.js";
	import {default as m3} from "./src/js/m3.js";
	// 有名称上的冲突,需要用别名来解决
	console.log(school,teach)
	console.log(gui,teach1)
	console.log(m3)
</script>

3.简便方式 (针对默认暴露)

<script>
	import m3 from "./src/js/m3.js";
</script>

暴露抛出来的是一个对象,引入也是对象,就是对象的结构解析,如let{a,b}={a:...,b=....}

浏览器使用ES6的模块化方式二

app.js文件

// 入口文件

//模块引入
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";

console.log(m1)
console.log(m2)
console.log(m3)
<script  src="./src/js/app.js" type='module'></script>
4.2.ES6-babal对模块化代码的转换

1.安装工具 babel-cli babel-preset-env browserify(webpack)

2.npx babel src/js -d dist/js

3.打包

4.3.lncludes方法

lncludes方法用来检测数组中是否包含某个元素,返回布尔类型值

4.4.

在ES7中引入指数运算符「**」,用来实现幂运算,功能与Math.pow结果相同

二、ES8


1.1.ES8的async函数
async function fn(){
	//返回一个字符串
    //return '@@@'
    //返回的结果不是一个 Promise 类型的对象,返回的结果就是成功 Promise 对象
    //抛出错误,返回的结果是一个失败的 promise
    //throw 呢哇 Error('出错啦!')
    //返回的结果如果是一个 Promise 对象
    return new Promise((resolve,reject) => {
        resolve('成功的数据')
    })
}

const result = fn()

//调用 then 方法
result.then(value => {
    console.log(value)
},reason => {
    console.warn(reason)
})

这里的返回值如果不是一个Promise对象,则默认返回一个成功状态的promise,如果你不显式的return一个值,则默认返回undefined。

1.2.await表达式

一般与async函数一起使用,当await定义的Promise对象返回的是一个失败的值,那么就要与try...catch...结合使用,使用try...catch...来捕获错误。

如何体现await与async函数的异步操作:只要有一个await语句后的promise对象是reject,那么整个async函数都会中断执行。

1.3.async与await结合发送ajax请求

async 与 await 测试

// 发送 AJAX 请求,返回的结果是 Promise 结果
        function sendAjax(url) {

            return new Promise((resolve, reject) => {
                // 1.创建对象
                const x = new XMLHttpRequest()

                // 2.初始化
                x.open('GET', url)

                // 3.发送
                x.send()

                // 4.事情绑定
                x.onreadystatechange = function () {
                    if (x.readyState === 4) {
                        if (x.status >= 200 && x.status < 300) {
                            // 成功!
                            resolve(x.response)
                        } else {
                            // 如果返回是一个错误的结果
                            reject(x.status)
                        }
                    }
                }
            })
        }

        // Promise then 方法测试
        sendAjax("https://api.apiopen.top/getJoke").then(value => {
            console.log(value)
        }, reason => {

        })

        // async与await结合发送Ajax请求
        async function fn() {
            let re1 = await sendAjax('https://api.apiopen.top/getJoke')
            console.log(re1)
        }
        fn()
1.3.ES8的扩展
// 声明对象
const school = {
    name:'@@',
    cities:['43','##','$$'],
    xueke:['adf','dsf','sdf','sdfg']
}

//获取对象所有的键
console.log(object.keys(school));//获取对象所有的值
console.log(object.values(school));/ / entries
console.log(object.entries(school));//创建Map
const m = new Map(Object.entries(school));
console.log(m.get( 'cities ' ));

三、ES9


1.1.ES9扩展运算符与rest参数

Rest参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符。

//1.
function connect({host,port, ...user}){
    console.log(host);
    console.log(port);
    console.log(user); 
}
connect({
    host: '127.0.0.1',
    port: 3306,
    username: 'root',
    password: 'root',
    type: 'master'
});
// ---- 输出的是 127.0.0.1,3306,root,root,master

//2.
const skill1 = {
    q:'!!',
    w:'@@'
}
// ... skill1 => q:'!!',w:'@@'
const skill2 = {
    e:'$$'

const skill3 = {
    r:'%%'
}
const mangseng = {...skill1,...skill2,...skill3}
console.log(magseng) //  q:'!!',w:'@@',e:'$$',r:'%%'


1.2.ES9正则扩展-命名捕获分组
// 声明一个字符串
let str1 = '<a href="http://www.atgui.com">尚硅谷</a>'
// /提取 url 与 【标签文本】
const reg = /<a href="(.*)">(.*)<\/a>/
const result = reg.exec(str1)
console.log(result)
---result.group:undefined

// 命名捕获分组
let str2 = 'a href="http://www.atgui.com">尚硅谷</a>'
const reg = /<a href="( ?<ur1>.*)">(?<text>.*)<\V/a>/;
const result = reg.exec(str2);
console.log(result.groups.ur1);
console.log(result.groups.text);

四、ES10


1.1.ES10对象扩展方法—Object.fromEntries

方法 Object.fromEntries() 把键值对列表转换为一个对象,这个方法是和 Object.entries() 相对的。

//二维数组
const result = Object.fromEntries([
    [ 'name','尚硅谷'],
    [ 'xueke' , 'Java,大数据,前端,云计算']
]);
console.log(result)
---
    {name:"尚硅谷",xueke:"Java,大数据,前端,云计算"}

//Map
const m = new Map()
m.set('name','11')
const result = Object.fromEntries(m)
console.log(result)
----
	{name:"11"}
//Object.entries ES8
const arr = Object.entries({
    name:"11"
})
console.log(arr)
---
    [Array(2)]
0:(2) ["name","11"]
1.2.数组扩展方法–flat与flatMap
//flat
//将多维数组转化为低位数组
const arr1 = [1,2,3,4,[5,6]]
console.log(arr1.flat())
--- [1,2,3,4,5,6]
const arr2 = [1,2,3,4,[5,6,[7,8,9]]]
//参数为深度,是一个数字
console.log(arr2.flat(2))
--- [1,2,3,4,5,6,7,8,9]

//flatMap
const arr3 = [1,2,3,4]
const result1 = arr3.flatMap(item => item * 10)
console.log(result1)

五、ES11


1.1.ES11-私有属性
class Person {
    //公有属性
    name;
    //私有属性
    #age;
    #weight;
    
    //构造方法
    constructor(name,age,weight){
        this.name = name;
        this.#age = age;
        this.#weight = weight
    }

    intro(){
        console.log(this.name)
        console.log(this.#age)
        console.log(this.#weight)
    }
}
//实例化
const mm = new Person('meimei',18,'45kg')
1.2.ES11-Prmoise.allSettled属性
//声明两个promise对象
const p1 = new Promise((resolve, reject)=>{
    setTimeout(() => {
    	resolve('商品数据-1');
    },1000)
});
const p2 = new Promise((resolve, reject)=>{
    setTimeout(() => {
    	resolve('商品数据- 2');// reject('出错啦!');
	},1000)
});
//调用 allSettled 方法
const result = Promise.allSettled([p1,p2])

//调用 all 方法
const result1 = Promise.all([p1,p2])

//allSettled得出的结果是一个数组,数组里面包含了Promise对象的状态与value值
//all如果数组中的所有的Promise对象的状态都为成功的,那么将输出所有该数组中Promise对象中的键值,如果有一个Promise对象的状态为失败,那么all的状态则为失败的。
1.3.ES11-可选链操作符
function main( config){
    // const dbHost = config && config.db &8 config.db.host;
    const dbHost = config?.db?.host;
    console.log(dbHost);
    }
main({
    db:{
    	host: ' 192.168.1.100',username: "root'
    },
    cache: {
    	host: '192.168.1.208' ,username: ' admin'
    }
})

选用可选链操作符不会显示相关报错。

1.4.ES11-动态import

一般为了维护,会选择用动态引入模块。

//import * as m1 from "./hello.js";//获取元素
const btn = document.getElementById('btn');
btn.onclick = function(){
        import('./hello.js').then(module => {
        module.hello();
	});
}
1.5.ES11-BigInt类型
//大整形,在定义好的整形数据后放一个n,则表示这个数据为最大整形数据
// let n = 521n;
// console.log(n,typeof(n));

//函数,可以通过BigInt这个函数将整形转化为最大整形
// let n = 123;
// console.log(BigInt(n));
// 但是不能是除整形类型数据的其他类型数据
// console.log(BigInt(1.2));

//大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);
console.log(max + 1);
console.log(max + 2);
console.log(BigInt(max))

console.log(BigInt(max) + BigInt(1))
console.log(BigInt(max) + BigInt(2))

1.6.ES11-绝对全局对象globalThis

使用场景:由于子啊 Number 与 BigInt 之间进行转化回损失精度,因而建议仅在值可能大于253时使用 BigInt 类型,并且不在两种类型之间进行相互转化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值