ES6

ES6

let和var的区别?

  1. let是块级作用域,var是函数作用域

  2. let不存在变量声明提升,var有声明提升

  3. let有暂时性死区,(TDZ)【需要满足先声明后使用的原则】

  4. let不能重复声明变量

  5. let和const声明的变量不在与浏览器的顶层对象window的属性挂钩,var或function声明的变量会在window的属性中体现出来

    1.注意块级作用域
    2.暂时性死区
    3.不存在变量提升
    4.同一作用域内不允许重复声明
    

const的注意事项

  1. const声明的时候要赋值(初始化赋值),否则报错
  2. const声明的变量后续不可在赋值修改,否则报错

const的用法

  1. 必须在声明的时候赋值,否则报错
  2. 不能修改
  3. const声明的对象类型,对象或数组内部得值可以改
  4. const声明的常量建议使用大写

结构赋值

解构赋值的作用是将数组或对象中地值解构出来赋值给变量

解构赋值重点理解“模式”的概念

什么是模式:所谓的模式就是赋值运算符左边的[]或{},赋值运算符右边是对象或数组

  1. 结构赋值的作用是将数组或对象中的值解构出来赋值给变量,示例:

    let [a,b,c]=[1,2,3];
    数组或对象中的内容小于模式匹配的内容,被认为是解构不成功,反之为不完全结构
    let [a,b]=[1,2,3] 不完全结构
    let [a,b,c,d]=[1,2,3] 结构不成功
    基于解构不成功,提出了默认值的概念,默认值生效的条件是:数组或对象中的内容严格等于undefined,则默认值生效
    let [a,b,c,d=4]=[]
    数组解构赋值的妙用:交换值
    let a=1;
    let b=2;
    [a,b]=[b,a]
    //spread和rest运算符
    
  2. 重点!对象的解构赋值(key也是模式)

    let {title}= {title:'雪碧'}//使用简写模式
    let {title:title}={title:'雪碧'}
    let {title:t} = {title:'雪碧'}
    示例:
    let obj={
    	info:[
    		{
    			name:'雪碧',
    			age:'1'
    		},{
    		
    		}
    	]
    }
    obj.info[0].name//正确
    obj.info[1].age//错误
    对象解构赋值的默认值
    let {title,name:'xuebi'}= {title:'黎明'}//简写
    let {title,name:name='lishi'}
    
  3. 重点!函数形参解构赋值

    function fun ({type='GET',datatype='json'}={}){
    	//TODO 
    }
    fun({type:'GET',datatype:'xml'})
    fun({type:'POST'})
    fun()
    

    字符串是类数组,数组又是特殊的对象,所以有了下面的解构形式:

    let {0:a,1:b,2:c}='abc'
    这种形式的解构写法,语法允许但毫无意义
    

模板字符串

模板字符串(可以接受回车或者换行或空格(回车换行和空格最终可以体现到dom中)变量的嵌入很方便)

好处:

  1. 模板字符串为构造多行字符串和字符串拼接带来了更加方便的方式
  2. 统一模板字符串可以通过使用不同的标签,对模板进行进一步处理,输出不同的结果
传统拼串
let title='周三';
let str ='<div>'+ title +'</div>'
模板字符串拼串
let str =`<div>${title}</div>`
let str = `
	<div>
		<h1>${title}</h1>
		<p>段落</p>
	</div>
`
多行拼串
let a=`In JavaScript \n is a line-fead`
let b=`In JavaScript this
not legal`;

标签模板

标签指的是函数名,模板指的是函数的实参(es6模板字符串形式的实参)

let a = 5;
let b = 10;
fun`${a+b}world${a}hello${a*b}`
等同于
tag(['hello','world',''],15,50)
标签模板的第一个参数是一个数组,用来接受模板中的非变量部分
标签模板的第二个参数或后面的参数,用来接受模板中的变量部分
function fun(){
	console.log(arguments);
}

深拷贝

深拷贝、浅拷贝指的都是对象数据类型的拷贝

**原理:**js的深拷贝发生在对象的赋值上,对象赋值的时候仅仅是一个引用赋值,也就是说两个不同变量名指向的是同一份内存空间;基本数据类型则不存在这样的行为;要完成对象的深拷贝需要使用递归遍历所有对象的属性进行赋值,也可以使用JSON.stringify和JSON.parse操作

默认的对象拷贝是浅拷贝

let arr = [1,1,3];
let arr1= arr;
arr[0]= 4;

使用json完成深拷贝

let m= [1,2,3];
let n = JSON.parse(JSON.stringify(m));//深拷贝

spread扩展运算符

spread运算符的表示是:’…'三个点表示

  1. 数组使用扩展运算符

    var arr=[1,3,4]

    console.log(…arr)

    场景:函数的接收参数

    …运算符在函数形参中出现,被认为是rest剩余参数运算符

    所谓的剩余参数指的是,出了…前面德参数之外,所有的实参都存到args参数里,所以args参数是一个数组

    剩余参数运算符应该出现在形参列表的末尾

    当…运算符出现的在函数形参中的时候,表示rest剩余参数运算符

对象属性名简写和属性名表达式

对象属性名简写

let x = 10;
let title = 'xuebi'
let obj={
	x,
	file:function(){
		console.log('1')
	},
	discuss(){
		console.log('2')
	}
}
obj[title]='可乐'

对象属性名表达式

let obj ={};
obj.title='雪碧';//属性名是字符串
obj['age']='1';//属性名是字符串
obj[title+1] = '可乐';//属性名表达式(重点理解表达式概念)
console.log(obj)
对象在新增属性名的时候可以后字符串形式或表达式形式两个做法
取出对象属性内容的时候也可以是字符串或表达式

symbol

symbol是ES6新增的数据类型,也就是说symbol是es6中的第七种数据类型

它的作用是产生独一无二的值

它的使用场景:

  1. 给对象属性名赋值,防止被覆盖

  2. 模拟class私有变量

    console.log(Symbol());
    console.log(typeof Symbol())
    严重注意:symbol()每次调用都要产生一个独一无二的值
    使用场景:给对象属性名赋值,防止被覆盖
    let obj={};
    obj[Symbol()]='你永远找不到我';
    console.log(obj[Symbol()]);
    //改进
    let key = Symbol();
    let obj={};
    let obj[key]='你永远得不到我';
    console.log(obj[key]);
    symbol带描述符的用法
    console.log(Symbol('电影')===Symbol('电影'));
    symbol.for 的用用法(for的key如果一样,则symbol.for产生的内容就是一样的)
    console.log(Stmbol.for('电影')===Symbol.for('电影'))
    

Promise


Promise用来解决异步回调问题,由于js是单线程的,很多异步操作都是依靠回调方法实现的,这种做法在逻辑比较复杂的回调嵌套中会相当复杂;也叫做回调地狱;promise用来讲这种繁杂的做法简化,让程序更具备可读性,可维护性;promise内部有三种状态,pedding、fulfilled、rejected;pedding表示程序正在执行单位得到结果,及异步操作没有执行完毕,fulfilled表示程序执行完毕,且执行成功,rejected表示执行完毕但失败;这里的成功和失败都是逻辑意义上的;并非要报错,其实,promise和回调函数一样,都是要解决数据的传递和消息发送问题,promise中的then一般对应成功后的数据处理,catch一般对应失败后的数据处理。

resolve表示成功的状态
reject表示失败的状态
var p = new Promise(function(resolve,reject){
	setTimeout(()=>{
		resolve('成功');
		reject('失败')
	})
})
resolve对应then的回调结果
reject对应catch的回调结果
p.then(function(rst){
	console.log(rst)
}).catch(function(err){
	console.log(err)
})

链式操作

promise的then的链式操作,then内部的return返回,如果return是promise对象,则下一个then调用者是promise对象,如果return的是非promise对象数据,则该数据作为下一个then的回调函数参数,链式的then只处理resolve,then默认返回一个promise对象,这个默认promise就是上一次执行的promise对象

var p = new Promise(function(resolve,reject){
	setTimeout(()=>{
		resolve('成功')
	})
})
p.then()是一个链式操作,也就是说then方法内部会返回一个promise对象,这个promise默认就是当前promise对象
then的回调函数参数是由resolve来触发调用的
p.then(function(rst){
	console.log(rst)
	return '成功1'
}).then(function(rst){
	console.log(rst)
}).catch(function(err){})

Promise_all

var p1 = new Promise(function(resolve,reject){
	setTimeout(function(){
		reject('p1失败')
	},1000)
})
var p2 = new Promise(function(resolve,reject){
	setTimeout(function(){
		reject('p2失败')
	},1000)
})
p1和p2在数组中的次序决定了rst结果集中的顺序
all里面的promise对象如果有一个失败则全部失败,不会返回任何成功结果
p1(true) && p2(true)	执行then
p1(false) && p2(true)	执行catch
p1(true) && p2(false)	执行catch
p1(false) && p2(false)	执行catch
Promise.all([p1,p2]).then(function(rst){
	console.log(rst)
}).catch(function(err){
	console.log(err)
})

promise_race

var p1 = new Promise(function(resolve,reject){
	setTimeout(function(){
		resolve('p1失败')
	},1000)
})
var p2 = new Promise(function(resolve,reject){
	setTimeout(function(){
		resolve('p2失败')
	},1000)
})
Promise.race([p1,p2]).then(function(rst){
	console.log(rst)
}).catch(function(err){
	console.log(err)
})

Promise简写

var p1 =new Promise.resolve($.get('http://www.bestqingshan.top/demo/ajaxWeather.php'))
p1.then(function(rst){
	console.log(rst)
})

函数参数默认值

ES5中的默认值设置
function fun(x){
	x = x ===undefined ? 1 : x;
	console.log(x)
}
ES6中默认值使用
function fun(x=1){
	console.log(x)
}
fun();//默认值生效
fun(2);//默认值不生效
fun(undefined);//默认值生效
fun(null);//默认值不生效

箭头函数

  1. 箭头函数是匿名函数,不能绑定自己的this、arguments、super、new、target
  2. 箭头函数会捕捉其所在上下文的this值,作为自己的this值,在使用call/apply绑定时,相当于只是传入了参数。对this没有影响
  3. 箭头函数不绑定arguments,取而代之用rest参数…解决
  4. 箭头函数当方法使用的时候,没有定义this绑定
  5. 箭头函数不能作为构造函数,和new一起用就会抛出错误
  6. 箭头函数没有原型属性
  7. 不能简单返回对象字面量

try…catch

try...catch捕获的是运行错误,不是语法错误(语法错误在程序编译的时候就被检查出来)
使用try...catch的目的是让程序更加健壮
try{
	let obj={}
	if(JSON.stringify(obj)=='{}'){}
	let a = obj.info.age
} catch (err){
	console.log(err)
}

面向对象

面相对象(oop):面向对象是相对于面向过程而言的
面向过程:解决问题的时候,把问题过程化和步骤化去解决。
面向对象:把问题拆解归类,然后描述的是类与类,类与对象,对象与对象的关系
	类:具备相同属性和行为的事务的抽象,所以类是用来描述属性和行为地
	对象:对象是类的一个实例化,对象应该具备类所描述的行为的属性
了解面向对象:重点了解:属性、行为、对象和类,他们之间的关系

class Animal{
	constructor(){
		this.type = '动物'
	}
}
class Tigger extends Animal {
	constructor(){
		super();
		this.name = '雪碧'
	}
}
let tigger = new Tigger();
console.log(tigger.type)

Class

class Animal {
	/**
		类是用来描述属性(变量)和行为(方法)的
		var type;
		this.type
		constructor是ES6内置的方法,是一个构造方法使用new实例化一个对象的时候构造方法自动被调用,不要手动调用该方法
		constructor构造方法的作用是用来初始化(初始化属性,初始调用一些方法)
	**/
	constructor(Newname,Newage){
		//属性的描述应该放在constructor里面,否则报错
		//var type = ''//局部变量
		this.type = '动物';//成员变量
		this.name = Newname;
		this.age = Newage;
	}
	sayHi(){
		console.log(this.type)
		//方法内部访问属性,使用this
	}
}
var animal = new Animal('雪碧',1)
animal.sayHi();

class用法this指向

new操作符都进行了什么操作?

new Object()

  1. 创建一个空对象,
  2. 调用对象的constructor
  3. 返回经过constructor构造方法初始化过所有属性和方法的新对象

两个对象是绝对不可能相等的

let a = {}

let b = {}

if (a===b){}

通过对象使用的属性或方法叫做成员变量和成员方法,成员变量和成员方法是属于对象,也就是说每个对象都有一份属于自己的属性和方法

与成员变量和成员方法相对的是静态变量合静态方法(类变量和类方法);因为类的声明不能重复(重复报错)所以静态变量或静态方法是独一份,是属于当前类的

this指的是当前调用者,谁调用就是谁(注意箭头函数内的this)

class静态

class Animal{
    static type = '动物';//静态属性不要写到constructor里面
	constructor(Newname){
        //成员属性
        this.name = Newname
    }
	//成员方法
	sleep(){
        console.log(this);
        console.log('特别的睡姿')
    }
	//静态方法
	static eat(){
        console.log(this);
        console.log('吃')
    }
}
/**
	成员变量和成员方法归对象所有
	静态变量和静态方法归类所有
**/
let animal = new Animal('雪碧');
animal.sleep();
console.log(Animal.type);
Animal.eat()

class属性

public:公有(属性或方法在类内部或类外部或子类都可以访问到)
protect:保护(属性或方法只能在类内或子类使用)
private:私有(属性或方法只能造当前类内使用)
var siyou = Symbol('私有');
class Animal{
	constructor(){
		this.type = 'haha'
	}
	//获取方法getter
	getType(){
		return '$'+this.type
	}
	//设置方法setter
	setType(newType){
		if(newType == null) return;
		this.type = newType;
	}
	[siyou](){}
}
let animal = new Animal();
console.log(animal.type)
animal.type = 'hehe'

class继承

class Animal{
	static type = '动物';
	constructor(Newname){
        //super();报错在没有继承关系的类里面不能使用super
        this.name = Newname;
    }
	static eat(){
        console.log('饿了么');
    }
	sleep(){
        console.log('睡觉');
    }
	ts(){}
}
//父类-子类, 超类-子类, 超类-派生类
class Tigger extends Animal {
    constructor(Newname,Newage){
        //super.sleep();报错,因为super方法还没有完成初始化
        //super方法必须出现在constructor的第一行
        super(Newname);//调用父类的构造方法,来初始化父类属性;
        this.age = Newage;
		//super.sleep()可以
    }
    /**
    	覆盖:子类方法和父类方法同名,会覆盖父类方法,在调用的时候父类方法不可见
    	当父类方法不能满足子类需求的时候,子类可以选择覆盖父类方法
    	覆盖是一种多态表现,多态是为了统一接口调用
    **/
    sleep(){
        //super();报错;super方法只能出现在constructor里面,否则报错
        //super对象用来调用父类中被子类覆盖的方法,出现在方法中
        super.sleep();
        this.ts();
        console.log('睡不着')
    }
    ts(){
        //super.sleep()
    }
}

let tigger = new Tigger('雪碧',1)
//成员变量和成员方法
console.log(tigger.name);
tigger.sleep();
tigger.ts()
//静态变量和静态方法
console.log(Tigger.type)
Tigger.eat();

补充

class Chef {
			title = '';
			constructor(food) {
				this.food = food;
				this.dish = [];
			} //getter

			get menu() {
				console.log('getter');
				return this.dish;
			} //setter

			set menu(dish) {
				console.log('setter');
				this.dish.push(dish);
			}

			cook() {
				console.log(this.food);
			}
		}
		Chef.title = ''; //当class不支持static属性的时候可以采用这种方式

		let zhangsan = new Chef();
		console.log(zhangsan.title);

总结

  1. class的基本语法写法
  2. class中的constructor的作用:
    • 初始化属性
    • 初始化方法调用
  3. 方法的简写
  4. this的指向
    • new一个对象的过程
    • 成员和静态内的this指向
  5. 静态变量和静态方法的写法
  6. 继承的写法
  7. super的两种用法
    • super方法
    • super对象
class类中super有哪些用法?
super有两种用法,一个是super方法,一个super对象,super方法只能出现在constructor方法中,super对象一般出现在子类覆盖父类的方法中
静态和成员的区别
静态的变量或方法归类所有,全局独一份,成员的变量或方法归对象所有,每次实例化对象成员方法和成员变量就会得到一份拷贝,对于一些通用的属性或方法,可以考虑设置为静态

async…await

async…await

  1. async是修饰方法的
  2. await必须出现在async修饰的方法中,否则报错
  3. async修饰的方法内部默认返回一个promise对象,在async修饰的方法中return数据,数据会作为promise对象的resolve参数
  4. await等待的异步操作一般是promise操作,当promise的状态变为fulfilled的时候await不在等待,程序得以继续执行,等待过程中,程序处于中断暂定状态,await的等待结果是resolve函数的参数。
  5. await不等待reject的执行结果,如果要处理reject需要使用try…catch或者promise.catch
//async...await用法
//async...await用来等待promise的resolve执行结果,等待同步方法没有明显意义
function fn(){
    //同步操作
    console.log('同步')return '1';
    //异步操作
    var  p = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            reject('456')
        },1000)
    })
    return p ;//必须return 要返回promise对象,否则await不会等待
}
async function fun (){
    //await不能单独使用,需要出现在由async修饰的方法中
    console.log('123')
    let rst = await fn();
    /**
    1.处理await的reject结果
    try{
    	var rst = await fu();
    } catch(error){
    	console.log(error)
    }
    2.处理await的reject结果
    var rst = await fn().catch(err=>{
		console.log(err)
	})
    **/
    console.log('789')
    return rst
}

fun().then(rst=>{
    console.log(rst)
})

callback

const WEATHER = 'ajaxWeather.php';
const TEST = 'ajax.php';
const REGISTER = 'ajaxRegister.php';
const LOGIN = 'ajaxlog.php';

class Http{
    constructor(){
        this.baseUrl = 'https://www.bestqingshan.top/demo/'
    }
    common({url,type='GET',data={}}={}){
        url = this.baseUrl + url;
        var p = new Promise((resolve,reject)=>{
            $.ajax({
                type,
                url,
                data,
                dataType:'json',
                success:function(response){
                    resolve(response)
                },
                error:function(err){
                    reject(err)
                }
            })
        })
        return p;
    }
    async weather(callback){
        await this.common({url:WEATHER})
    }
    async register(callback){
        let rst = await this.common({url:REGISTER,type:'POST',data})
        callback(rst)
    }
    login(data){
        return this.common({
            url:LOGIN,type:'POST',data
        })
    }
}

iterator迭代器,遍历器

iterator作用:统一数据结构(数组,对象,map,set,数组包对象,对象包数组)的遍历方式

在数据结构上部署iterator接口:所谓的部署接口表现形式为,给对对象或数组等集合增加iterator属性,属性的内容是一个根据iterator接口规范自行实现的办法

//示例一:说明iterator接口的书写规范
var it = makeIterator(['a','b']);
console.log(it.next());//{value:'a',done:false}
console.log(it.next());//{value:'b',done:false}
console.log(it.next());//{value:undefined,done:true}
//makeIterator的作用是创建一个遍历器方法
function makeIterator(array){
    var nextIndex = 0;
    retrun {
        next:function(){
            return nextIndex < array.length ? {value:array[nextIndex++],done:false} : {value:undefined,done:true}
        }
    }
}
//示例二:给对象部署iterator接口,iterator接口的默认属性是Symbol.iterator
//一、对象iterator接口遍历
const obj = {
    [Symbol.iterator]:function(){
        var count = 10;
        var index = 0;
        return {
            next:function(){
                //done:false和value:undefined都可以省略
                if(index<count){
                    return {value:index++,done:false}
                } else {
                    return {value:undefined,done:true}
                }
            }
        }
    }
}
var objNoIterator = {
    title:'周五',
    age:1,
}
for(item of obj){
	console.log(item)   
}
for(item of objIterator){
    console.log(item)
}
二、数组iterator接口遍历
var names = ['马龙白兰度', '纪梵希', '奥黛丽赫本', '猫王', '玛丽莲梦露', '迈克杰克逊', '麦当娜'];
inames = names[Symbol.iterator]();
console.log(inames.next())
for (item of names){
    console.log(item)
}
三、字符串iterator接口遍历
let str = 'helloworld';
1.iterator遍历
istr = str[Symbol.iterator]();
console.log(istr.next());
2.for...of遍历
for(item of str){
    console.log(item)
}

iterator小结:iterator的目的是迭代器,遍历数据结构,提供了统一遍历数据结构的接口

Generator:生成器

generator和async…await的关系

async…await是基于promise的generator语法糖

状态机:什么是状态?所谓的状态就是变量内容,状态机的意思就是说可以管理或存储多个变量

generator函数的特征是function关键字和函数名之间有*,函数内部有yieid表达式

function* fnGenerator (){
	var a = 'hello';
    yieid a;
    var b = 'wprld';
    yieid b;   
}
//generator方法调用后会返回一个遍历器对象,该对象可以使用next或for...of遍历
var fn = fnGenerator();
console.log(fn.next());
//generator函数内部没有yieid表达式的时候,此时调用f()内部的代码也不会执行,除非执行了next

iterator是遍历器,给数据结构提供统一的遍历接口(for…of)

for…of和forEach的区别?

for…of内部支持break,continue,return,forEack不行

for…of和for…in的区别?

for…in会把对象的原始属性都遍历出来,但是for…of没有这样的缺点

set和map

set和array是对应关系
map和object是对应关系
set集合里面不允许重复值
var arr = [1,23,33,223,44,55,2,1]
let arr1 = [...new Set([1,2,3,1,2,3])];
console.log(arr)
//判断空对象
if(JSON.stringify({})==='{}'){}
var obj = {
	title:'雪碧',
	age:500
};
console.log(Object.keys(obj))
console.log(Object.values(obj))
console.log(Object.entries(obj))

var map = new Map();
map.set(1,1);
map.set('1','1')
map.set(ture,true);
map.set([1,2,3],[1,2,3]);
map.set({title:'周五'},{title:'周五完了'})
console.log(map.get([1,2,3]))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值