let和const:
在ES5中作用域分为全局作用域和函数作用域。
在ES6中作用域分为全局作用域、函数作用域和块作用域。
let使用
let块作用域实例:
for(let i=1;i<3;i++){
console.log(i);
}
此时let定义的i只能在for循环里使用。
PS:let不能重复定义一个变量。
const使用:
1.const声明的是常量,不可修改
2.const声明时就要赋值。
3.const声明对象时,里面的内容可以修改。
实例:
function test(){
const PI=3.1415926; //PI不可修改
const k={
a:1
}
k.b=3; //此时修改的不是k 而是k里面的内容所以2、3不冲突
consloe.log(PI,k);
}
解构赋值
作用:赋值。
解构:左边一个结构,右边一个结构,左右一一对应赋值。
解构赋值的分类:
1.数组解构赋值
{
let a ,b;
[a,b]=[1,2];
console.log(a,b);
}
2.对象解构赋值
{
let a,b;
{{a,b}={a:1,b:2}}
console.log(a,b)
}
3.字符串解构赋值
4.布尔解构赋值
5.函数参数解构赋值
6.数字解构赋值
PS:如果解构赋值中没有在解构上成功配对,则取默认值为undefind
ES解构赋值适用于变量交换
嵌套取值实例:
let mataDate={
title:'abc',
test:[{
title:'test',
desc:'description'
}]
}
let{title:esTitle,test:[{title:cnTitle}]}=mataDate(); //函数值赋值给let对象
console.log(esTitle,cnTitle); //输出title
正则扩展
正则新增特性
1.构造函数的变化
2.正则方法的扩展
3.u修饰符 //用来匹配Unicode编码
4.y修饰符
{
let s='bbb_bb_b';
let a1=/b+/g;
let a2=/b+/y;
conslog.log('one',a1.exec(s),a2.exec(s)); //g修饰符是全局修饰符。第一次匹配为bbb,第二次匹配bb。匹配规则是只要有字符串为bb就匹配
conslog.log('two',a1.exec(s),a2.exec(s)); //y也是全局修饰符,第一次匹配bbb,第二次为null,第二次匹配开始从_所以为null
}
PS:sticky用于判断是否开启y修饰符
5.s修饰符 //匹配各种换行符 但es6还未实现
实例:
{
let regex=new RegExp(/xyz/ig,'i'); //声明一个正则表达式对象。此时修饰符'i'可以覆盖签名正则表达式用的修饰符ig
console.log(regex.flags); //flags用来获取正则表达式的修饰符属性
}
字符串扩展
字符串新增特性
1.Unicode表示法
当Unicode大于0xFFFF时需要加入{} 大于两个字节
实例:
{
console.log('a',`\u0061`); // a a
console.log('s',`\u20BB7`); // s 口7
console.log('s',`\u{20BB7}`); // s 吉
}
2.遍历接口
{
let str='\u{20bb7}abc'
for(let code of str){
console('es6',code);
}
}
api:
{
let str ="String";
console.log('include',str.includes('r')); //判断是否包含r字符
console.log('start',str.startWith('str')) //判断是否以str开头
console.log('end',str.endWith('ng')) //判断是否以ng结尾
}
{
let str="abc";
console.log(str.repeat(2)); //重复字符串abc两次
}
3.模板字符串
{
let name ="list";
let info ="hello world";
let m=`i am ${name},${info}`;
console.log(m); // i am list hello world
}
{
console.log("1".padStart(2,"0"));//作用补白 如果返回字符串不是2位则以0开头补全
console.log("1".padEnd(2,"0")); //如果返回字符串不是2位则以0结尾补全
}
//标签模板
{
let user ={
name:'list',
info:'hello world'
};
console.log(abc`i am ${user.name} ,${uesr.info}`);
function abc(s,v1,v2){
console.log(s,v1,v2);
return s+v1+v2;
}
}
//输出 ["i am",",","",raw:Array[3]] "list" "hello world"
// i am ,,,list hello world
{
console.log(String.raw`Hi\n${1+2}`); //Hi\n3
console.log(`Hi\n${1+2}`);
// Hi
// 3
}
4.新增方法(10种)
数值扩展
数值处理新增特性
1.新增方法
{
//ES6中二级制以0b或0B开头
console.log(0b111110111); //输出503
//ES6中八进制以0o或0O开通
console.log(0o767); //输出 503
console.log(Number.isFinite(15)); //判断数字是否有穷尽 true
console.log(Number.isFinite(NaN)); //false
console.log(Number.isInteger(25)); //true 判断是否是整数
console.log(Number.isInteger(25.0)); //true
console.log(Number.isInteger(25.1));//false
console.log(Number.isInteger('25'));//false
console.log(Number.MAX_SAFE_INTEGER); //9007199254740991 常量 存储最大数值
console.log(Number.MIN_SAFE_INTEGER);//-9007199254740991 存在数值下限
console.log(Number.isSafeInteger(10)); //true 判断数字在是否在安全数上下限之内
console.log(Math.trunc(4.1));//4 取整数 只取整数位
console.log(Math.sign(-5)); // -1 判断数字是否位正负0
console.log(Math.sign(5)); // 0
console.log(Math.sign(0)); // 1
console.log(Math.sign("foo")); // NaN
console.log(Math.cbrt(-1)); //求立方根
}
2.方法调整
数组扩展
数组新增特性
1.Array.of //将一组数据变量转换位数据类型
{
let arr =Array.of(3,4,5,7,9);
console.log(arr);
}
2.Array.from //将集合转换位数组
3.CopyWithin //在当前数组内部 将指定位置的成员复制到其他成员位置
{
console.log([1,2,3,4,5].CopyWithin(0,3,4)); // [4,2,3,4,5]
// 0表示从那个位置开始替换
// 3表示从那个位置开始读取
// 4表示从那个位置截至
}
4.find\findIndex //查找
{
console.log([1,2,3,4,5,6].find(function(item){return item>3})); // 输出4 只找到第一个符合的元素
console.log([1,2,3,4,5,6].findIndex(function(item){return item>3})); //输出3 返回下标
}
5.fill
{
//填充数组,全部替换
console.log('fill',[1,'a',undefined,fill(7)]); //输出[7,7,7]
console.log(['a','b','c'].fill(7,1,3)); //输出['a',7,7] 7为替换的内容 1为起始下标 3为替换长度
}
6.entries\keys\values
{
for(let index of ['1','c','ks'].keys()){
console.log('keys',index); //输出 0 1 2
}
for(let values of['1','c','ks'].values()){
console.log('values',values); //输出 1 C ks
}
for(let [index,value] of['1','c','ks'].entries()){
console.log('values',index,value); //输出 0 1
// 1 c
// 2 ks
}
}
7.includes
{
console.log([1,2,3,NaN].includes(1)); //判断是否包含1
}
函数扩展
函数新增特性
1.参数默认值
{
function test(x,y='world'){
console.log(x,y);
}
test('hello'); //输出 hello world
test('hello' ,'hello') //输出 hello hello
}
2.rest参数
{
function test(...arg){ //可变长参数
for(let v of arg){
console.log(v);
}
}
test(1,2,3,4); //输出 1 2 3 4
}
3.扩展运算符 //rest参数的逆运用
{
console.log(...[1,2,3]); //输出 1 2 3
}
4.箭头函数
{
let arrow = v => v*2; //arrow函数名 v函数参数 v*2函数返回值
let arrow2 =()=>5; //无参用()表示
console.log(arrow(3)); //输出6
}
5.this绑定
6.尾调用
{
function tail(x){
console.log(x);
}
function fx(x){
return tail(x);
}
fx(123); //输出 123 用于代码优化 提升性能
}
Symbol
1.Symbol概念 //就是该种类型提供独一无二的值 声明的值不重复不相等
{
let a1=Symbol();
let a2=Symbol();
console.log(a1===a2); //false
let a3=Symbol.for('a3'); //先检测全局有没有该声明 如果没有则注册,如果有则返回原有的
let a4=Symbol.for('a4');
console.log(a3===a4); //true
}
2.Symbol的作用
{
let a1=Symbol.for('abc');
let obj={
[a1]:'123',
'abc':345,
'c':456
};
console.log(obj); //Object{abc:345,c:456,Symbol(abc):"123"}
for(let [key,value] of Object.entries(obj)){
console.log(key,value); //输出 abc:345 c:456 此时无法遍历出Symbol声明的abc
}
//若要取到abc的值则需要使用Object.getOwnPropertySymbols(obj).forEach()
Object.getOwnPropertySymbols(obj).forEach(function(item){
console.log(obj[item]); // 123 只拿出了Symbol的值
})
// 如果需要拿Symbol中的值和非Symbol中的值则使用Reflect.ownKeys(obj)
Reflect.ownKeys(obj).forEach(function(item){
console.log(item,obj[item]);
})
}
数据结构
1.Set的用法 //值唯一
//声明
{
let list =new Set();
list.add(5);
list.add(7);
console.log(list.size); //获取长度
console.log(list.has(5)); //判断是否存在元素
list.delete(5);//删除元素
list.clear();//清除所有元素
//遍历元素
for(let value of list){
console.log(value);
}
//遍历元素的另一种方法
list.forEach(function(item){console.log(item);})
}
//声明并赋值
{
let arr=[1,2,3,4,5];
let list=new Set(arr);
}
2.WeakSet的用法
//支持的元素只能是对象 不能是数值
//弱引用
//没有clear方法
//不能遍历
{
let weakList =new WeakSet();
let arg={};
weaklist.add(arg);
}
3.Map的用法
{
let map =new Map();
let arr=['123'];
map.set(arr,456);
console.log(map,map.get(arr));// {['123']=>456} 456
//size 获取长度
//delete 删除
//clear 清空
// 遍历如set一样
}
4.WeakMap的用法
//弱引用
//没有size
//不能遍历
{
let weakmap = new WeakMap();
}
5.Map和Array的对比
{
//数据结构横向对比 增、删、改、查
let map =new Map();
let array=[];
//增
map.set('t',1);
array.push({t:1});
//查
let map_exist=map.has("t");
let array_exits=array.find(item=>item.t);
//改
map.set("t",2);
array.forEach(item=>item.t?item.t=2:'');
//删
map.delete("t");
let index=array.findIndex(item=>item.t);
array.splice(index,1);
}
6.Set和Array的对比
{
//set和Array的对比
let set =new Set();
let arr=[];
//增
set.add({t:1});
arr.push({t:1});
//查
let set_exist=set.has({t:1});
let array_exits=array.find(item=>item.t);
//改
set.forEach(item=>item.t?item.t=2:'');
array.forEach(item=>item.t?item.t=2:'');
//删
set.forEach(item=>item.t>set.delete(item):'');
let index=array.findIndex(item=>item.t);
array.splice(index,1);
}
7.Map、Set和Object的对比
{
//map、set、object的对比
let item={t:1};
let map =new Map();
let set =new Set();
let obj={};
//增
map.set('t',1);
set.add({t:1});
obj["t"]=1;
//查询
let map_exist=map.has("t");
let set_exist=set.has({t:1});
let obj_exist='t' in obj ;
//改
map.set("t",2);
set.forEach(item=>item.t?item.t=2:'');
obj["t"]=2;
//删除
map.delete("t");
set.delete(item);
delete obj["t"];
}
Proxy和Reflect
1.Proxy和Reflect的概念
{
let obj ={
time:"2019-08-10";
name:"net";
_r:123
};
//反射获取obj中的time
//console.log(Reflect.get(obj,'tiem'));
//反射设置obj中name
//Reflect.set(obj,'name','web');
//Reflect.has(obj,'name') //判断obj中是否有name属性
let monitor =new Proxy(obj,{
//拦截对象属性的读取
get(target,key){
return target[key].replace('2019','2018') ;
},
//拦截对象设置属性
set(target,key,value){
//只能设置name属性
if(key==='name'){
return target[key]=value;
}else{
return target[key];
}
},
//拦截key in object操作
has(target,key){
//只能删除_r属性
if(key==='name'){
return target[key];
}else{
return false;
}
},
//拦截delete
deleteProperty(target,key){
if(key.indexOf('_')>-1){
delete target[key];
return true;
}else{
return target[key];
}
},
// 拦截Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames
ownKeys(target){
//过滤time属性
return Object.keys(target).filter(item=>item!="time");
}
});
console.log(monitor.time) // 2018-08-10
monitor.name="java";
console.log(monitor); //{time:"2018-08-10",name:"java",_r:123}
console.log('name' in monitor);//true
}
2.Proxy和Reflect的适用场景
{
function validator(target,validator){
return new Proxy(target,{
_validator:validator,
set(target,key,value,proxy){
if(target.hasOwnProperty(key)){
let va =this._validator[key];
if(!!va(value)){
return Reflect.set(target,key,value,proxy)
}else{
throw Error(`不能设置${key}到${value}`)
}
}else{
throw Error(`${key}不存在`);
}
}
})
}
const personValidators={
name(val){
return typeof val==="string"
},
age(val){
return typeof val ==='number' && val>18
}
}
class Person{
constructor(name,age){
this.name =name ;
this.age =age;
return validator(this,personValidators)
}
}
const person =new Person('lilei',30);
}
类
类的概念
1.基本语法
{
//基本定义和生成实例
class Parent{
constructor(name="java"){
this.name=name;
}
}
let v_parent =new Parent("v");
}
2.类的继承
{
//继承
class Parent{
constructor(name="java"){
this.name=name;
}
}
class Child extends Parent{
constructor(name="child"){
super(name);
//新增属性
this.type="child";
}
}
}
3.静态方法
{
class Parent{
constructor(name="java"){
this.name=name;
}
static tell(){
}
}
//通过类来调用
Parent.tell();
}
4.静态属性
{
class Parent{
constructor(name="java"){
this.name=name;
}
static tell(){
}
}
//静态属性
Parent.type="test";
}
5.getter、setter
{
//getter、setter
class Parent{
constructor(name="java"){
this.name=name;
}
get longName(){
return this.name;
}
set longName(value){
this.name=value;
}
}
}
Promise
1.异步
2.Promise的作用
3.Promise的基本语法
实例
{
let ajax =function(){
console.log("执行");
return new Promise(function(resolve,reject){
//rsolvee 执行下一步操作
//reject 中断操作
setTimeout(function(){
resolve()
},1000);
})
};
ajax().then(function(){
console.log("promise","timeout2");
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve();
},2000);
});
}).then(function(){
console.log("timeout3");
})
}
//执行过程中有异常错误
{
let ajax =function(num){
console.log("执行");
return new Promise(function(resolve,reject){
if(num>5){
resolve();
}else{
throw new Error("出错了");
}
})
}
ajax(6).then(function(){
console.log("log.6");
}).catch(function(err){
console.log(err);
})
}
//使用场景
{
//所有图片加载完毕再添加到页面
function loadImg(src){
return new Promise((resolve,reject)=>{
let img =documetn.createElement('img');
img.src =src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(imgs){
imgs.forEach(function(img){
document.body.appendChild(img);
})
}
//将多个promise实例当作一个promise实例。
Promise.all({
loadImg("xxxxxx");
loadImg("xxxxxx");
loadImg("xxxxxx");
}).then(showImgs)
}
//先到先得图片加载
{
function loadImg(src){
return new Promise((resolve,reject)=>{
let img =documetn.createElement('img');
img.src =src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(img){
let p=document.createElement("p");
p.appendChild(img);
document.body.appendChild(p);
}
Promise.race({
loadImg("xxxxxx");
loadImg("xxxxxx");
loadImg("xxxxxx");
}).then(showImgs)
}
Iterator
1.Iterator和for...of循环
2.什么是iterator接口 //遍历循环
3.iterator的基本语法
{
let arr=["hello","world"];
let map =arr[Symbol.iterator]();
map.next();
}
//自定义interator
{
let obj ={
start:[1,2,3],
end:[2,3,4],
[Symbol.iterator](){
let self =this;
let index =0;
let arr=self.start.concat(self.end);
let len =arr.lenget;
return{
next(){
if(index
Generator
1.基本概念 //异步编程一种解决方案
//基本语法
{
//Genertor基本定义
let tell =function* (){
yield 'a';
yield 'b';
return c;
}
let k =tell();
}
//使用generator作为iterator遍历器的返回值
{
let obj ={};
obj[Symbol.interator]=function*(){
yield 1;
yield 2;
yield 3;
}
for(let value of obj){
console.log(value);
}
}
//状态
{
let state =function*(){
while(1){
yield "A";
yield "B";
yield "C";
}
}
let status =state();
console.log(status.next()); //A
console.log(status.next()); // B
console.log(status.next()); // C
console.log(status.next()); // A
console.log(status.next()); // B
console.log(status.next()); // C
}
//async语法
{
let state =async function(){
while(1){
await "A";
await "B";
await "C";
}
}
let status =state();
console.log(status.next()); //A
console.log(status.next()); // B
console.log(status.next()); // C
console.log(status.next()); // A
console.log(status.next()); // B
console.log(status.next()); // C
}
2.next函数的用法
3.yield*的语法
//抽奖实例
{
let draw =function(count){
//具体的抽奖逻辑
console.info(`剩余${count}次`);
}
let residue =function *(){
while (count>0){
count --;
yield draw(count);
}
}
let star=residue(5);
let btn =doucument.createElemetn("button");
btn.id="start";
document.body.appendChile(btn);
document.getElementById('start').addEventListenner('click',function(){
star.next();
},false)
}
//长轮询
{
let ajax=funciton* (){
yield new Promise(function(resolve,reject){
setTimeout(function(){
resolve({code:0});
},200);
})
}
let pull =function(){
let genertaor =ajax();
let step =genertaor.next();
step.value.then(function(d){
if(d.code!=0){
setTimeout(function(){
console.log("wait");
pull();
},1000);
}else{
console.log(d);
}
})
}
}
Decorator
1.基本概念 //修饰器,是一个函数 用来修改一个类的行为
2.基本语法
//安装插件 babel-plugin-transform-decorators-legacy
//在babelrc中添加插件 "pulgins":["transform-decorators-legacy"]
{
let readonly =function(target,name,descriptor){
descroptor.writable=false;
return descriptor
};
class Test{
@readonly
time(){
return '2019-08-11';
}
}
let test =new Test();
console.log(test.time())
}
//实例2
{
let typename=function(target,name,descriptor){
target.myname="hello";
};
@typename
class Test(){
}
console.log("类修饰符",Test.myname);
}
//修饰器第三方库 core-decorators;
//日志系统
{
let log =(type)=>{
return function(target,name,descriptor){
let src_method=descriptor.value;
descriptor.value=(...arg)=>{
src_method.apply(target,arg);
console.log(`log${type}`);
}
}
}
class AD{
@log("show")
show(){
console.info("ad is show");
}
@log("click")
click(){
console.log("ad is click");
}
}
let ad =new AD();
ad.show();
ad.click();
}
模块化
1.基本概念
2.ES6的模块化语法
{
//导出变量
export let A=123;
//导出喊出
export function test(){
console.log("test");
}
//导出类
export class Hello{
test(){
console.log("clss");
}
}
//引入
import {A,test,Hello} from "";
}