【12-20】ES5复习、ES6新增、

一、ES5新增的内容

我们说的ES5和ES6其实就是在 js 语法的发展过程中的一个版本而已

1、 数组的相关方法:

    1-1. 数组.forEach(function (item, index, arr) {})

    1-2. 数组.map(function (item, index, arr) {})

    1-3. 数组.filter(function (item, index, arr) {})

    1-4. 数组.every(function (item, index, arr) {})

    1-5. 数组.some(function (item, index, arr) {})

2、 严格模式

    2-1. 使用"use strict"定义严格模式

    2-2. 严格模式可以定义在函数的最顶端或程序的最顶端

    2-3. 在严格模式下 在变量a 没有声明时 a = 10 ; 这样的赋值会报错,定义两个相同名称的函数参数也会报错

    2-4. 严格模式执行效率更高

3、 this指向

    每一个函数内部都有一个关键字是 this

    【函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有关系】

3-1.全局定义的函数直接调用时,this=>window

  function fn(){
      console.log(this); //window
    }

    fn();

3-2.对象内部的方法调用,this => 调用者(对象)

  var obj = {
      name:"zhangsan",
       age:18,
       say:function(){
         consoloe.log(this); //方法内部的值是obj
       }
    }

3-3.事件处理函数,this => 事件源

  写法一:

   odiv.onclick = function(){
       consoloe.log(this); //事件源odiv
    }


  写法二

    odiv.onclick = fn;
    function fn(){
       consoloe.log(this); //事件源odiv
    }

  写法三:

  <button onclick = "fn(this)">点我</button>

    function fn(a){
       console.log(a); //a是实参this,指的是点击的button按钮
    }

3-4.定时器内部的this指向winodw

 setTimeOut(function(){
     consoloe.log(this); //事件源window
    },10000)
    setInterval(function(){
     consoloe.log(this);//事件源window
    },10000)

3-5.自调用函数,this => window

(function(){
  consoloe.log(this); //window
})()

4、 使用call()、bind()、apply()强行改变this指向

  4-1. call()
    语法: 函数名.call(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...)
    注意:会立即执行函数

    第一个参数是你要改变的函数内部的 this 指向

    第二个参数开始,依次是向函数传递参数

function fn(x,y){
        console.log(x);
        console.log(y);
        console.log(this.age);
    }

    var obj = {
        age: '18'
    }

    fn(1,2); // 输出的结果是1 2 undefined 原因是fn函数是全局函数,全局函数的 this指向window

   
    需求:想将fn内部的this指向obj,这样的话,就可以使用this.age访问到18
     call:
      作用:改变this指向的
      语法:函数名.call(obj,参数1,参数2...)
      注意:1. 会调用函数
            2. fn中this指向改变成obj

      fn.call(obj,1,2);// 输出的结果是1 2 18

  4-2. apply()

    语法: 函数名.apply(要改变的 this 指向,[要给函数传递的参数1, 要给函数传递的参数2, ...])

    注意:会立即执行函数

    第一个参数是你要改变的函数内部的 this 指向

    第二个参数是一个数组,数组里面的每一项依次是向函数传递的参数

    function fn(x,y){
        console.log(x);
        console.log(y);
        console.log(this.age);
    }
    var obj = {
        age: '18'
    }

    fn(1,2); // 输出的结果是1 2 undefined 原因是fn函数是全局函数,全局函数的 this指向window

   
    需求:想将fn内部的this指向obj,这样的话,就可以使用this.age访问到18
    apply:
    作用:改变this指向的
    语法:函数名.apply(obj,[参数1,参数2...])
    注意:1. 会调用函数
         2. fn中this指向改变成obj

    fn.apply(obj, [1, 2])  // 输出的结果是1 2 18

        

  4-3. bind()

    语法: var newFn = 函数名.bind(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...); newFn(传递参数)

    返回值:返回一个已经改变了 this 指向的函数

    function fn(x,y){
        console.log(x);
        console.log(y);
        console.log(this.age);
    }
    var obj = {
        age: '18'
    }

    fn(1,2); // 输出的结果是1 2 undefined 原因是fn函数是全局函数,全局函数的 this指向window

    bind():
    作用:改变this指向的
    语法:函数名.bind(obj,参数1,参数2...)
    注意
         1. 函数返回一个已经改变了this指向的函数
         2. fn中this指向改变成obj

    var newfn = fn.bind(obj, 1, 2)
    newfn();// 输出的结果是1 2 18

【总结】

   1. call===>函数名.call(obj,参数...)

   2. apply===>函数名.call(obj,[参数...])

   3 .bind===>var fn =  函数名.call(obj,参数...);

                       fn();


二、ES6新增的内容

let和const关键字

1、let/const和var的区别:

    1-1. 预解析:var会进行预解析,let/const不会

1. 预解析:var会进行预解析,let/const不会
var命令会发生"变量提升"现象,也就是预解析,即变量可以在声明之前使用,值为undefined。
这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。
// var 的情况
console.log(foo);// 输出undefined
var foo = 2;

// let 的情况
console.log(bar);// 报错   ReferenceError
let bar = 2;
也就意味着被let声明的变量,必须先定义在使用。

    1-2. 变量重名:var定义变量可以重名,let/const不允许在同一个作用域下,定义重名变量

2. 变量重名:var定义变量可以重名,let/const不允许在同一个作用域下,定义重名变量
var a = 123;
var a = 123; //可以实现

let b = 123;
let b = 123; //Identifier 'a'has already been declared

    1-3. 块级作用域:var没有块级作用域,let/const有

3.块级作用域:var没有块级作用域,let/const有
{
   var a = 10;
   let b = 123;
}
console.log(a);//输出的结果是10
console.log(b);//输出的结果是 报错:Uncaught ReferenceError: b is not defined

上面代码在代码块之中,
分别用let和var声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量无法被打印,
var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。

再如:
for(let i=0; i<10; i++){
   document.write(i);//输出的结果是 0123456789
}
document.write(i);//输出的结果是 报错:Uncaught ReferenceError: b is not defined

上面代码中,计数器i只在for循环体内有效,在循环体外引用就会报错。

2、let和const的区别

          let可以被重新赋值, const不可以被重新赋值

          const声明即赋值, let可以先声明,后赋值

2-1. let用来声明变量,它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,类似于C,C++,JAVA局部变量的概念。

2-2. const命令用来声明常量,一旦声明,其值就不能改变。也就是只读变量。    

2-3. const的基本用法

const a=10;
a=100; //输出结果 Assignment to constant variable.报错

a.声明常量
const PI = 3.1415;
console.log(PI) // 3.1415
PI = 3; // 输出结果 报错:TypeError: Assignment to constant variable.

b.常量必须初始化
const foo; //输出结果 报错:Missing initializer in const declaration

c.块级作用域
{
    const foo = 123;
}
console.log(foo);//输出结果 报错:TypeError: Assignment to constant variable. 与let效果相同

d.声明不提升(const修饰的变量必须先定义后使用)
if (true) {
    console.log(MAX);// 输出结果 报错:Uncaught ReferenceError
    const MAX = 5;
}

3、字符串新增

  3-1. str.includes(元素)  在字符串中判断是否包含某个元素,返回的是布尔值

  3-2. str.startsWith(字符串) 判断字符串是否以某个字符串开始,返回布尔值

  3-3. str.endsWith(字符串) 判断字符串是否以某个字符串开始,返回布尔值

  3-4. str.repeat(n) 让字符串重复n次

4、箭头函数

  4.1 ES6 语法中定义函数的一种方式

  4.2 函数定义的方式:

     2.2.1 声明式 function fn() {}

     2.2.2 赋值式 var fn = function () {}

     2.2.3 箭头函数(赋值式的一种简化写法) var fn = () => {}

  2.3 箭头函数的特点

   2.3.1 当你的形参只有一个的时候, 可以不写小括号

   
    var fn = (a)=>{consloe.log(a)}

    //简写

    var fn = a=>{consloe.log(a)}

  2.3.2  当你的函数体只有一行代码时, 可以省略大括号不写

    var fn = (a)=>{consloe.log(a)}

    //简写

    var fn = a=>consloe.log(a)

  2.3.3 当你的函数体只有一行代码并且有return,return都可以不写

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

    //简写

    var fn = (a,b)=>a+b

2.3.4  箭头函数内部的this

          箭头函数内部不绑定this,箭头函数内的this指向箭头函数所在的上下文环境


三、解构赋值

快速从对象或者数组中获取一些数据,分为解构数组和解构对象

1、解构数组

    var arr = [12,43,32,3,32];
    console.log(arr[0],arr[1],arr[2],arr[3]); //输出结果为 12 43 32 3 32
    var [a,b,c,d,e]  = arr;
    console.log(a,b,c,d,e);//输出结果为 12 43 32 3 32


    【注】解构赋值的语法:var [a,b,c,d,e]  = arr;
    作用:相当于a,b,c,d,e分别存储的是12,43,32,3,32

2、解构对象

var obj = {name:"zhangsan",age:"18",sex:"男"}

console.log(obj.name,obj.age,obj.sex);//输出结果 zhangsan 18 男

console.log(obj['name'],obj['age'],obj['sex']);//输出结果 zhangsan 18 男

for(let k in obj){
    console.log(obj[k]);//只能使用[]语法,因为[]语法是支持变量的
}  //输出结果 zhangsan
   //         18 
   //         男

let {name,age,sex} = obj;
console.log(name,age,sex); //输出结果 zhangsan 18 男



【注】解构赋值的语法:let {name,age,sex} = obj;

3、解构赋值的用途

函数只能返回出来一个值,解构赋值可以让函数返回出来多个值

要求:1-100内所有的能被4整除的数字的个数,并且计算数字和

function getCount_Sum(){
       var sum = 0;
       var count = 0;
       for(var i = 1;i<=100;i++){
           if (i%4==0) {
               count++;
               sum+=i;
           }
       }
       return [sum,count];
   }

   var [sum,count] = getCount_Sum();

   console.log(sum); //1300
   console.log(count); //25

   console.log(getCount_Sum()); // [ 1300,25]

四、展开、合并运算符

1、展开数组

var arr = [12, 34, 45, 2];
    console.log(arr[0], arr[1], arr[2], arr[3]); //12 34 45 2

展开:将数组中的元素一一展开,等价于上面的写法

    console.log(...arr); //12 34 45 2

2、合并数组

合并: 将传递的实参以数组的形式接收,形参是一个数组形式

function fn(...arr) {
        console.log(arr); //[1,2,3,4,5]
        var sum = 0;
        arr.forEach(item => {
            sum += item;
        })
        console.log(sum); //15
    }

    fn(1, 2, 3, 4, 5);//arr = [1,2,3,4,5]

五、默认参数

概念:给函数的形参设置一个默认值, 当你没有传递实参的时候, 默认参数会生效

function fn(a = 4, b = 1) {
        console.log(a, b)
    }
    fn(1, 2);//1 2
    fn();// 4 1

六、字符串新增语法

1、语法:str.includes('子字符串')

      返回值:true/false

      作用:判断字符串str是否包含子字符串  

2、 语法: str.startsWidth('子字符串substr')

      返回值:true/false

      作用:判断str是否以substr开始

3、 语法: str.endssWidth('子字符串substr')

      返回值:true/false

      作用:判断str是否以substr结束

4、 语法:str.repeat(n) :      

      作用:让字符串重复n次

      返回值:重复后的字符串

5、模板字符串

var obj = {
        name:"zhangsan",
        age:18,
        sex:'男'
    }

    var oP =document.querySelector('p')
    oP.innerHTML = `我的姓名是${obj.name},性别是${obj.sex},年龄是${obj.age}`
    oP.innerHTML = '我的姓名是'+obj.name+',性别是'+obj.sex+',年龄是'+obj.age;

七、set和map集合

 1、set:数据结构,类似于数组

    Set:数据结构,类似于数组,但是它的值不会重复(自动去重)

    Set的属性:set.size获取元素的长度

    Set的方法:set.add(ele) 向Set中添加元素

                        set.delete(ele) 删除某元素

                        set.has(ele) 是否包含某个元素,返回布尔值

                        set.clear()  清空set集合

var set = new Set([1, 12, 3, 12, 1, 3]);
    console.log(set.size); //输出set去重后的个数  3

 增加一个元素
    set.add(18)
    console.log(set); //{1, 12, 3, 18}
    set.add(12)
    console.log(set); //{1, 12, 3, 18}

 删除一个元素
    set.delete(12)
    console.log(set); //{1, 3, 18}

 判断是否包含
    console.log(set.has(18)); // 返回true

 清空
    set.clear(); 
    console.log(set); // {size: 0}

 数组去重
    var arr = [12, 12, 21, 3, 21, 3];
    var set = new Set(arr);// 类似于数组,不是数组(就是伪数组)
    console.log(set); //{12, 21, 3}

 将伪数组转为真正的数组   --->真数组 =  Array.from(伪数组)
    var zArr = Array.from(set);
    console.log(zArr); // [12, 21, 3]


 简写:
    var arr = [12, 12, 21, 3, 21, 3];
    console.log(Array.from(new Set(arr))); // [12, 21, 3]

2、Map:数据结构,类似于对象

Map的属性:map.size获取元素的长度

Map的方法:map.set('key','value') 设置键值对

                     map.get(key) 获取某元素

                     map.delete(key) 删除某元素

                     map.clear() 清空map集合

                     map.has(key) 对象中是否包含某元素,返回布尔值

var map = new Map();
    console.log(map); //Map(0) {size: 0}
    map.set('name', 'zhangsan')
    map.set('age', '18')
    map.set('sex', '男')
    console.log(map);//Map(3) {'name' => 'zhangsan', 'age' => '18', 'sex' => '男'}

 如果想获取键的值
    console.log(map.get('name')); //zhangsan
    console.log(map.get('age'));  //18
    console.log(map.get('sex'));  //男

 刪除
    map.delete('name')
    console.log(map);//Map(2) {'age' => '18', 'sex' => '男'}

 遍历:map用的是for..of
    for (var item of map) {
         获取键(item[0])和值(item[1])
        console.log(item[0] + '-----' + item[1]); //name-----zhangsan
                                                  //age-----18
                                                  //sex-----男
    }
 清空
    map.clear();
    console.log(map); //Map(0) {size: 0}

八、for..of和for..in的小小总结

1、数组:for.in循环可以遍历数组,遍历的是下标(字符串类型)

           for.of可以遍历数组,遍历的是值

var arr = [12, 34, 12, 5, 6]
    for (var k in arr) {
        console.log(k);//k代表的是字符串形式的下标 
                       // 0 1 2 3 4
    }

    for (var k of arr) {
        console.log(k);// k代表的是数组元素
                       // 12 34 12 5 6
    }


2、对象:for..in循环遍历对象

           for..of不可以遍历对象

var obj = { name: 'zhangsan', age: 18 }
    for (var k in obj) {
        console.log(k + '---' + obj[k]);//name---zhangsan
                                        //age---18
    }

    // for..of不能遍历对象
    for (var k of obj) {
        console.log(k); //报错 Uncaught TypeError: obj is not iterable
    }


3、map集合:for..of可以遍历map集合

                  for..in不能遍历map集合

 var map = new Map();
    map.set('name', 'zhangsan')
    map.set('age', '18')
    map.set('sex', '男')
    console.log(map); //Map(3) {'name' => 'zhangsan', 'age' => '18', 'sex' => '男'}

    for (var k of map) {
        console.log(k); //['name', 'zhangsan']
                        // ['age', '18']
                        // ['sex', '男']

        console.log(k[0] + '---' + k[1]); //name---zhangsan
                                          //age---18
                                          //sex---男
    }

上一篇:js笔记寒假01


下一篇:es6转es5 (babel)