J48 ES6

183 阅读10分钟

1.基础语法

  • 1.let和const
let a=12;
    a=13;
console.log(a);//=>13
  • 2.基于const创建变量,变量存储的值不能被修改(常量)
const b=12;
      b=13;
//=>Uncaught TypeError: Assignment to constant variable.
console.log(b);

2.let和var的区别

  • 1.let不存在变量提升(当前作用域中不能在let声明前使用变量)
  • 2.同一个作用域中 let不允许重复生命
  • 3.let解决了typeof的一个暂时性死区问题
  • 4.全局作用域中使用let声明的变量并没有给window加上对应的属性
  • 5.let会存在块作用域(除对象以外大括号都可被看作块级私有作用域)

3.箭头函数及this问题

  • 1.ES6中新增了创建函数的方式:'箭头函数'
  • 2.真实项目中是箭头函数和function这种普通函数混合使用

1.箭头函数简化了创建函数代码

const fn=([形参])=>{
        //函数体 return
    };
    fn([实参]);

2.形参只有一个,小括号可以不加

const fn=n=>{};

3.函数体中只有一句话,并且是return XXX的,可以省略大括号和return等

//箭头函数写法:
const fn=n=>n*10;

function fn(n){
    return function(m){
        return m+(++n);
    }
}
//改写箭头函数:
const fn=(n)=>m=>m+(++n)

4.箭头函数中没有arguments,但是可以基于剩余运算符获取实参集合,而且ES6中式支持给形参设置默认值的

  • ...arg:剩余运算符(把除第一项外的,其他剩余实参信息都存储到args这个数组集合中)
let obj={};
let fn=(context)=>{
console.log(arguments);
//=>Uncaughe ReferenceError:arguments is not defined 箭头函数中没有arguments    
};
fn(obj,10,20,30);
fn();
let obj={};
let fn=(context=window,...args)=>{
console.log(args);    
};
fn(obj,10,20,30);
//context的this:obj arg:[10,20,30]
fn();
//=>context的this:window arg[]

5.箭头函数中没有自己的this,他里面用到的this,都是自己所处上下文中的this(真实项目中,一但涉及this问题,箭头函数慎用)

  • 1.箭头函数开始的执行主体是window
window.name='WINDOW';
   let obj={
       name:'OBJ'
   }
   let fn=n=>{
       console.log(this.name);
   }
   fn(10);//=>this:window
   fn.call(obj.onclick)=fn;
   // =>this:window  不是我们预期的OBJ
   document.body.onclick=fn;
   // =>this:window 不是我们预期的BODY
  • 2.箭头函数开始的执行主体是window
 window.name='WINDOW';
   let fn=n=>{
       console.log(this.name);
   }
   let obj={
       name:'OBJ'
   }
   obj.fn(10);//=>this:window
  • 3.普通函数中有箭头函数,谁吧普通函数执行,this就是谁
 let obj={
   name:"OBJ",
   fn:function(){
   //=>this:obj普通函数是有自己的this的
   let f=()=>{
       console.log(this);
   }
   f();//=>this:obj
   return f;
    }
   }
   let f=obj.fn();
   f();//=>this:obj
  • 4.真实项目中的一个应用
let obj={
name:'OBJ',
fn:function(){
   //=>this:obj
   //=>原本期望的需求是:1s后把OBJ中的name改为“张三”
   //1.箭头函数最佳方案
   setTimeout(()=>){
   console.log(this);//=>OBJ
   this.name='张三';
   },1000);
   
   //2.普通函数的this是window
   setTimeout(function(){
   console.log(this);//=>window
   this.name='张三';
   },1000);

   //3.把需要的变量存储起来
   let _this=this;//=>把需要的this提前用变量存储起来
   setTimeout(function(){
       _this.name='珠峰';//=>需要使用的时间拿出来用即可
   },1000);}
}
obj.fn();

4.解构赋值

让左侧出现和右侧值相同结构,以此快速获取到我们需要的内容真实项目中最常用的就是对数组和对象的结构赋值

1.数组的结构赋值

let ary=[10,20,30,40,50];
let n=ary[0],
    m=ary[1],
    x=ary.slice(2);
    console.log(n,m,x);
    //=>10,20,30
  1. 解构赋值写法
  • ...x扩展运算符:把剩下的内容存储到x中(x是个数组),但是他只能出现在最后
let ary=[10,20,30,40,50];
let [n,m,...x]=ary;
console.log(n,m,x);
//=>10 20[30,40,50]

3.数组中不出现第二项值

let ary=[10,20,30,40,50];
let [n, , m]=ary;
console.log(n,m);//=>10 30

4.如果没有这一项,我们可以基于等号赋值默认值

let ary=[10,20,30,40,50];
let [n, , m, , , x=0]=ary;
console.log(n,m,x);//=>10 30 0

5.数组嵌套解构取值

let ary=[10,[20,30[40,50]]];
let [n, [ , ,[ ,m]]]=ary
console.log(n,m);//=>10 50

6.对象的解构赋值

let obj={
    name:'王三峰 ',
    age:79,
    sex:'BOY',
    friends:['唐二一','郭一','王一二','郭三']
};
let {
    name,
    sex
}=obj;
console.log(name,sex);//=>王三峰  BOY

7.: 冒号相当于给获取的结果设置了一个别名(变量名);创建了一个叫做nianling的变量存储于了obj.age的值

let obj={
    name:'王三峰 ',
    age:79,
    sex:'BOY',
    friends:['唐二一','郭一','王一二','郭三']
};
let{
    age:nianling
}=obj;
console.log(nianling);//=>79

8.= 等号给获取的记过设置默认值(没有这个属性走的是默认值)

let obj={
    name:'王三峰 ',
    age:79,
    sex:'BOY',
    friends:['唐二一','郭一','王一二','郭三']
};
let{
    height="180cm"
}=obj;
console.log(height);//=>'180cm'

9.多维对象获取

let obj={
    name:'王三峰 ',
    age:79,
    sex:'BOY',
    friends:['唐二一','郭一','王一二','郭三']
};
let{
    name,
    friends:[firstFriend]
}=obj;
console.log(name,firstFriend);//=>王三峰 唐二一

10 真实项目中的应用

  • 从服务器获取的DATA数据
let data={
'code':0,
'data':{
    'today':'2019-08-07',
    'data':[{
        'date':'2019-07-17',
        'number':'17',
        'weekday':"\u661f\u671f\u4e09"
    },{
         'date':'2019-07-18',
        'number':'9',
        'weekday':"\u661f\u671f\u56db"
    }]
},
'version':"17917d337ccb7c4d34624b73efdfa0c0"
};

10-1 获取data对象中的today

let {
    code,
    data:{
      today,
      data:calenderData
}}=data;
console.log(code,today,calenderData);
//=>0 "2019-08-07" [{...},{...}]

10-2 拿到数组weekday:

//1.方法一结构
calenderData.forEach(item=>{
	let {
		weekday,
		date
	}=item;
console.log(weekday,date);
//=>星期三 2019-07-17,星期四 2019-07-18
});
//2.每一项作为形参
calenderData.forEach(({
	weekday,
	date
	})=>{
	console.log(weekday,date);
	//=>星期三 2019-07-17,星期四 2019-07-18
});

5.‘...’的三个作用

1.扩展运算符(多用在结构赋值中)

let [n,...m]=[12,23,34];
console.log(n,m)
//n:12
//m:[23,34]

2.展开运算符(多用在传递实参中)

//求数组中最小值
let ary=[12,23,13,24,10];
let min=Math.min(...ary);
console.log(min);//=>10

//数组克隆(浅克隆)
let ary=[12,23,13,24,10];
let cloneAry=[...ary];
console.log(cloneAry);//=>[12,23,13,24,10]

//对象克隆(浅克隆)
let obj={name:'圆圆',age:16};
let cloneObj={...obj,sex:'girl',age:17};
console.log( cloneObj);
//=>{name: "圆圆", age: 17, sex: "girl"}

3.剩余运算符(多用在接受实参中)

let fn=(n,...arg)=>{
    //n:10
    //ary:[20,30]
}
fn(10,20,30);

6.class创建类

class Fn{
    //1.等价于之前的构造函数体
    constructor(){
        this.x=100;
    }

    //2.直接写的方法就是加在原型上的
    getX(){
        console.log(this.x);
    }

    //3.给实例设置的私有属性
    y=200;
    
    //4.前面设置static的:把当前FN当做普通对象设置的键值对
    static queryX(){}
    static z=300;
}

//2.也可以在外面单独这样子写
Fn.prototype.getY=function(){}

let f=new Fn(10,20);
f.getX();
FN.queryX();

Fn();
//=>Uncaught TypeError:class constructor Fn cannot be invoked 'new'
//=>class创建的类只能new执行,不能当做普通函数执行

7.ES6中的模板字符串

我们真实项目中会大量进行字符串拼接操作(尤其是需要动态绑定数据:把现有的HTMl代码拼接成数据的HTMl字符创),传统的ES3语法模式下字符串非常麻烦

1.传统的拼接方式

let year='2019',
     month='8',
     day='09',
     
//=>题目:'您好,小伙伴!今天是2019年08月09日,今天天气很糟糕,马上就要下大雨了,呵呵呵~'

//1.传统的拼接方式
let res=‘您好,小伙伴!今天是 '+year+''年'+month+'月 +day+'',今天天气很糟糕,马上就要下大雨了,呵呵呵~;

//2.页面中的机构拼接:传统的拼接方式
let ID='box';
let html='<ul class=''list clear'' id='' '+ID+' ''>';

2.ES6的拼接方式

let year='2019',
    month='8',
    day='09';
//=>2.反引号(撇)tab健上面的(ES6模板字符串语法)
//=> ${}模板字符串中书写JS表达式的方式(凡是有输出结果的都可以被称为js表达式,一般都是一行搞定的)
let res=`您好,小伙伴!今天是${year}${month}${day}日,今天天气很糟糕,马上就要下大约了,呵呵!~~~~`;

//2.页面中的机构拼接:ES6模板字符串拼接方法
let ID='box';
let HTML=`<ul class= 'list clear' id='${ID}'>
  <li><a href='javascript::'>
      <img src='img/1.jpg' alt=''>
      <p></p>
      <span>¥3899</span>
      </a></li>
    </ul>`;

8.ES6原型新增的API

  • 1.forEach使用
var ary = [{ a: 100 }, { a: 200 }, { a: 300 }, { a: 400 }];
let fn = (item, index) => {
    //item和index 都是形参
    //item 是数组中的每一项
    //index 是每一项对应的索引
    console.log(item, index)// {a: 100} 0
                            // {a: 200} 1
                            // {a: 300} 2
                            // {a: 400} 3
    item.a = 1000;
    return 100;
}
//forEach没有返回值,
var t1 = ary.forEach(fn);//没有返回值
//map有返回值,是一个新数组,新数组是由每一个回调函数返回值决定的
console.log(t1)//undefined
  • 2.map 用法
//1.数组中的末尾加0
let fn = item => {
    return item + '0'
}
let ary = [100, 200, 300, 400];
let res2 = ary.map(fn);
console.log(res2);//=>["1000", "2000", "3000", "4000"]

//2.数组的前面加0
let fn = item => {
    return '0' + item
}
let ary = [100, 200, 300, 400];
let res2 = ary.map(fn);
console.log(res2);//=>["0100", "0200", "0300", "0400"]

//3.数组中每一位都加100
let fn = item => {
    return item += 100
}
let ary = [100, 200, 300, 400];
let res2 = ary.map(fn);
console.log(res2);//=>[200, 300, 400, 500]


//需求,把arr中的每一项加1000
var arr = [100, 200, 300, 400];
var newArr = arr.map((item) => 1000 + item);
console.log(newArr);//[1100, 1200, 1300, 1400]
  • 3.some的使用
//1.只要有个回调函数的返回值是true,则some的运行结果修饰true  
//2、一旦有一个回调函数结果是true  则后边的回调就不再执行了
var arr = [100, 200, 300, 400];
var bol = arr.some((item, index) => {
    //只要有一个对调函数的额返回值是true 则some的运行结果就是true
    console.log('1', item)
    return item > 600//100, 200, 300, 400
})
var bol2 = arr.some((item, index) => {
    console.log('2', item)
    return item > 200//100, 200, 300,大于200就是true 结果就是true后面的不在执行了
})
console.log(bol, bol2); //false true

  • 4.every的使用
//1.只要有个回调函数的返回值是false,则every的运行结果false  
//2、一旦有一个回调函数结果是false  则后边的回调就不再执行了
var arr = [100, 200, 300, 400];
var bol = arr.every((item, index) => {
    //只要有一个对调函数的额返回值是true 则some的运行结果就是true
    console.log('1', item)
    return item > 600//100 false
})
var bol2 = arr.every((item, index) => {
    console.log('2', item)
    return item > 200//100 false
})
console.log(bol, bol2); //false 
  • 5.filter 就是条件成立的数组放到一个新的数组中
// 过滤 把回调函数return值是true的值赋值一份放到新数组中
let ary = [1, 2, 3, 4]
let res1 = ary.filter(item => {
    return item > 2
})
let res2 = ary.filter(item => {
    return item <= 2
})
console.log(res1, res2);//=[3, 4] (2) [1, 2]
  • 6.reduce
//prex,next是形参 prev代表钱一项 next代表后一项
let ary = [1, 2, 3, 4]
let res3 = ary.reduce((prev, next) => {
    console.log(prev, next);// 1  2
                            // undefined 3
                            // undefined 4
})


//reduce  相加返回运算
let arr=[10,20,30,40,50];
let res=arr.reduce((prev,next)=>{
    console.log(prev,next);//=>10 20
                            //30 30
                            //60 40
                            //100 50
    return prev+=next;
});


//练习 使用reduce (传了实参100,prev默认值就是100) 实现数组求和  
let ary3 = [10, 20, 30, 40];
let res6 = ary3.reduce((prev, next) => {
 debugger
    return prev + next
}, 100)
console.log(res6);//=>200
  • 7.Object.is(1, 1)
Object.is(1, 1)//=true
Object.is(+0, -0)//=>false
  • 8.Object.assign 是把obj2合并到obj中,返回值是合并后的obj
var obj = { a: 1 }, obj2 = { b: 2 }
console.log(Object.assign(obj, obj2));//=>{a:1,b:2}

  • 9.object.keys() 把obj中的所有属性名组成一个新数组
var obj = { a: 123, b: 234, c: 345 }
console.log( Object.keys(obj))//=>["a", "b", "c"]

  • 10.object.value();把obj中的所有属性值组成一个新数组
var obj = { a: 123, b: 234, c: 345 }
console.log( Object.values(obj))//=>[123, 234, 345]