es61---ES6 语法---箭头函数,扩展运算符,异常处理

面试题中一般会让你用es6去写一些算法,考验你对es6语法的熟练度

一.let和const命令

es5 var 关键字 声明变量
es6 :
const 常量(只能读取 不能修改 只读)
let 普通变量 声明的变量只能在当前的代码块内部有效 不能提前声明
代码块 {} 简称代码块 作用域

undefined 声明了却没有值
is not defined 既没有声明,也没有值

let声明的变量只在代码块里边有效

{
    let aq=2;
    console.log(aq);  //2
}
console.log(aq);   //aq is not defined 

let声明的变量不可以提前声明

   {
        //console.log(a);  //a is not defined 不可以提前声明
        let a=2;
        a = 20;//let设置可以更改变量的值
        console.log(a);
    }

const 常量定义,不可以更改值

   {
        const g = 9.8;
        //g=20;    //const设置的为常量,不能更改
        console.log(g);
    }
let const 关于for循环的面试题

①var作用域作用域全局

   {
        for (var i = 0; i < 10; i++) {
            console.log(i);//每次声明的i的值只在括号里边起作用
        }
        console.log(i); //10  代码从上往下看,先跑完for循环,i输出就是10
    }

② 每次声明的i只在本轮循环内有效

   {
        for (let i = 0; i < 10; i++) {
            console.log(i);//每次声明的i的值只在括号里边起作用
        }
        console.log(i);  //i is not defined
    }

{
    let a = [];
    for (let i = 0; i < 10; i++) {
        a[i] = function () {
            return i;  
        }  //这样写数组里边会塞10个函数,使用的时候调用即可
    }
    console.log(a[0]());  //0
}

二.变量的解构赋值

面试题,将a,b的值颠倒 用加减法去颠倒值,不借用临时变量

	var a=3;
	var b=1;
	console.log(a, b);
	a=a+b;
	b=a-b;
	a=a-b;
	console.log(a, b);
①数组解构赋值

按照结构的对应,将数值解出来,值对应统一

	以前的赋值方式  
	let a=1,b=2,c=3
	//解构赋值
    {
        let [a,b,c]=[1,1,2];
         console.log(a, b, c);
         let [e, [[f], g]] = [1, [[2], 3]];
         console.log(e, f, g);
         let [q,w,e]=[1,2];
    	 console.log(q, w, e);  //1 2 undefined
    	 let [q,w,e]=[,1,2];
    	 console.log(q, w, e);  //undefined 1 2
         }
... 扩展运算符 数组 只能放在最后
 	let [h,...i]=[1, 2, 3, 4];
    console.log(h, i); //1 [2, 3, 4]
    不可以写成 let[...i,h]  只能放在最后,不能往前放
③字符串的遍历接口

字符串遍历 charAt:根据索引返回相应的字符
①for循环加charAt
② for in遍历 加 charAt
③ for of 遍历,遍历的是字符串中的每一个值,直接可以输出字符串中的值

   {
        let a = "abcdefg";
        for (let i = 0; i < a.length; i++) {
            console.log(a.charAt(i));
        }
        for (let key in a) {
            console.log(a.charAt(key));
        }
        //字符串的遍历器
        for (let char of a) {
        console.log(char);
    }
④模板字符串 ${} 反引号
{
   //以前的写法
    let m = 20;
    let b=a+m;
    console.log(b);
    
    let str = `abc${m}`;
    console.log(str);
    console.log(`bvfhdsbf${m}jndskfndsj`);
}
⑤实例:模板编译 (重点)

通过模板字符串,生成正式模板实例 <%=EJS%>
<%= 输出数据到模板(输出的是转义的html标签)

{
     es6 模板编译   现在只是了解   在node  去详细讲解
     目前使用的是HTML页面,无法解析,模板页面(页面后缀egs)可以解析出来
     目前举例是往字符串里边写,但其实这个是往页面里边直接写的
     页面里边绑定值都是<%=  %>
    //let  template="<ul><li>菜单1</li><li>菜单2</li></ul>";
    let data = ['小猫', '小花', '小黑', '小白'];
    let template = `
	<ul>
	<% for(let i=0; i < data.length; i++) { %>
	<li><%= data[i] %></li>
            <% } %>
	</ul>
    `;   
    console.log(template);
}

在这里插入图片描述

⑥es6 正则变化 flags 获取修饰符

修饰符 i :不区分大小写,g:全局查找

   {
        let a = new RegExp(/abc/ig, 'i');
        console.log(a);  ///abc/i  会用后边的修饰符覆盖前边的修饰符
        let b= new RegExp(/abc/ig, 'i').flags;
        console.log(b);  //i
     }

三.es6 函数的使用

参数问题

es6允许函数的参数写默认值

//原本的写法
  function show(x,y){
        x=x;
        y=y||"world";
        console.log(x, y);
    }
   show("hello", "");
   es6中可以直接写参数的默认值
    function show(x,y="world"){
        x=x;
        console.log(x, y);
    }
   show("hello");

与解构赋值默认值结合使用

	这里写必须是等号形式
    function show({x,y=2}){  这里的x相当于x=null
        console.log(x, y);
    }
    这里赋值必须是":"形式
    show({x:1,y:1});  //1 1
    show({});         //undefinde  2
    show({x:5});     //5 2
    show();          // Cannot destructure property `x` of 'undefined' or 'null'.无法对“undefined”或“null”的属性“x”进行解构。

箭头函数(重点)

箭头左边是参数,箭头右边是返回的值
一个参数

 	let f=v=>v;
    console.log(f(1));   //1
   	let f=function(v){
        return v;
    }

多个参数 用括号将参数括起来

	let a=(v,m)=>v+m;   带多个参,加括号就可以
	console.log(a(1, 3));
	let a=function(v,m){
    	return v+m;
	}

不带参数 写个括号就行

 	let b=()=>1;
    let b=function(){
        return 1;
    }

返回值也可以写到{ }里边

   let f=()=>{
        console.log(1);
    }
    f();
  
  	let a=(c,b)=>{
        return c+b;
    }
    console.log(a(1, 2));

其他写法
返回值是数组或者对象

	数组
    let a=()=>[1,2,3];
    console.log(a());  //[1,2,3]
    对象
    let b=()=>{a:1,b:2};
    console.log(b());  //这种写法不行,会报错,它会将后边的括号当返回值
    特殊情况下用括号括起来
    let b=()=>({a:1,b:2});  返回值是对象,在外边加一个括号
    console.log(b()); 

箭头函数+解构赋值

 	let a=({a,b})=>{
        console.log(a, b);
    }
    a({a:1,b:2});

方法回调函数变箭头(重点)

令上下文this指针一致
箭头取的是上文的this

函数体里边的this是定义时所在的对象,而不是使用时所在的对象

例1:

  	var arr=[1,2,3];   数组定义时所在的对象为window
    arr.map((val,index)=>{      
    	console.log(this);   输出Window对象
    });

    里边和外边保持this指针一致
    function Person(){
        this.sex=function(){
            console.log(this);      输出Person {sex: ƒ}
          /* setTimeout(function(){
                console.log(this);  普通写法输出window对象,上下文this指针不一致
            })*/
            setTimeout(()=>{
                console.log(this);   用箭头函数,输出Person对象,上下文this指针一致
            })
        }
    }
    var p=new Person();
    p.sex();

例2:

  function show(){
        console.log(this);   
    	setTimeout(function(){
        	console.log(this);
    	})
    }
    //show();   //外边.里边都输出window对象
   show.call({id:1});  外边this是{id:1},里边this是window对象,上下文不一致

  function show(){
        console.log(this);
       setTimeout(()=>{
            console.log(this);
        })
    }
    //show();     外边.里边都输出window对象
   show.call({id:1});  外边里边this都是{id:1}

例3:
虽然return里边的this在更改,但外边的this一致是{id:1},箭头函数上下文this指针保持一致

 function foo() {
        console.log(this);  
        return () => {
            return () => {
                return () => {
                    console.log('id:', this.id);
                };
            };
        };
    }

    var f = foo.call({id: 1}); //这句话保证了函数上文的this恒为{id:1}

    var t1 = f.call({id: 2})()(); // id: 1
    var t2 = f().call({id: 3})(); // id: 1
    var t3 = f()().call({id: 4}); // id: 1
  function foo() {
        console.log(this);
        return function (){
            console.log(this);
            return () => {
                console.log(this);
                return () => {
                    console.log('id:', this.id);
                };
            };
        }
    }

    var f = foo.call({id: 1});

    var t1 = f.call({id: 2})()(); // 1 2 2 2
    var t2 = f().call({id: 3})(); // 1 window window undefined
   var t3 = f()().call({id: 4}); // 1 window  window undefined
 let foo=()=> {
        console.log(this);
        return  ()=>{
            console.log(this);
            return () => {
                console.log(this);
                return () => {
                    console.log('id:', this.id);
                };
            };
        }
    }

    var f = foo.call({id: 1});

    var t1 = f.call({id: 2})()(); // window window window undefined

③箭头函数不适用的场合

箭头函数将this由“动态”变为“静态”。(this直接是上文的this,没有办法去进行更改)
第一个场合是定义对象的方法,且该方法内部包括this
对象里边的函数

const cat = {
  lives: 9,
  jumps: () => {
    this.lives--;
  }
}

第二个场合是需要动态this的时候,也不应使用箭头函数。
dom对象的事件

var button = document.getElementById('press');
button.addEventListener('click', () => {
  this.classList.toggle('on');  这里边的this是window全局变量
});

④箭头函数的嵌套

对象写在括号里边

function insert(value) {
  return {into: function (array) {
    return {after: function (afterValue) {
      array.splice(array.indexOf(afterValue) + 1, 0, value);
      return array;
    }};
  }};
}

insert(2).into([1, 3]).after(1); //[1, 2, 3]

let insert = (value) => ({into: (array) => ({after: (afterValue) => {
  array.splice(array.indexOf(afterValue) + 1, 0, value);
  return array;
}})});

insert(2).into([1, 3]).after(1); //[1, 2, 3]
 function Hello(){
        return {
            sayHello:function(){
                console.log("hello");
            }
        }
    }
    let Hello=()=>({sayHello:()=>"hello"})
    console.log(Hello().sayHello());

四.js严格模式 “use strict”

按标准写代码 规范书写

 {
        "use strict";
        //优点   提高代码的安全性   优化代码   提高运行速度
        x = 3.14;       // 报错 (x 未定义)
        console.log(x);
    }

五.异常处理

try {
  // new实例化错误
  throw new Error("错误");
} catch (err) {
  // 处理输出错误
  console.log(err);
}
<input type="text"/>
<button>计算</button>

	{ 
		$("button").click(function () {
            try {
                //抓异常的语句
                //出现异常   会抛出异常  catch
                let num = $("input").val();
                if (num < 0) {
                    throw  new Error("输入的值不能小于0!");
                }
                else {
                    alert(Math.sqrt(num));
                }
            }
            catch (err) {
                这里边可以做一些异常处理
                console.log(err);
            }
            finally {
                console.log("最后执行");
            }
        });
	}

六.es6数组的扩展

扩展运算符(重点)

1.拆开数组

    let [h,...i]=[1, 2, 3, 4];
    console.log(h, i);

    //拆开数组
    console.log(...[1, 2, 3, 4]);
    //拆开dom元素集合
    [...document.querySelectorAll('div')]

2.替换函数的apply方法

 function show(x,y){
        return x+y;
    }
    console.log(show.apply(null, [1, 2]));   //3
    console.log(show(...[1,2]));    //3

3.数组追加方法

push方法返回值是数组a的长度

    let a=[1,2,3];
    let b=[4,5,6];
    
    a.push(7,8,9);  //push方法写几个参数,便往里边追加几个参数
    console.log(a);  [1,2,3,7,8,9]
    
    console.log(a.push(b));  
    console.log(a);   (4) [1, 2, 3, Array(3)]
    a.push(...b);
    console.log(a);   [1,2,3,4,5,6]
     
    console.log(a.concat(b)); //[1,2,3,4,5,6]
    
    console.log(Array.prototype.push.apply(a, b));//6 返回值是数组长度
    console.log(a);  //[1,2,3,4,5,6]
    
 	//该方法的底层源码,前部分当数组传进去,后部分逐一追加进去
    function ArrayPush () {
        var n = TO_UNIT32(this.length);
        var m = %_ArgumentsLength();
        for (var i = 0; i < m; i++) { // 逐个复制元素
            this[i + n ] = %_Arguments(i);//取参数列表对象
        }
        this.length = n + m; // 修改数组的length
        return this.length;
    }

4.数组复制
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。

const a1 = [1, 2];
const a2 = a1;

a2[0] = 2;
a1 // [2, 2]
a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。

es5中复制数组的方法

const a1 = [1, 2];
const a2 = a1.concat();

a2[0] = 2;
a1 // [1, 2]

es6中扩展运算符复制数组

const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

5.合并数组

    let a=[1,2];
    let b=[3,4];
    let c=[5,6];
    console.log(a.concat(b).concat(c));
    console.log(a.concat(b, c));
    console.log(a);  //concat数组追加方法不会改变原数组
    
    let d= [...a,...b,...c];
    console.log(d);

6.与解构赋值相结合

如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

	const [first, ...rest] = [1, 2, 3, 4, 5];
	first // 1
	rest  // [2, 3, 4, 5]

	const [first, ...rest] = [];
	first // undefined
	rest  // []

	const [first, ...rest] = ["foo"];
	first  // "foo"
	rest   // []

7.将字符串转为数组。

[...'hello']   //[ "h", "e", "l", "l", "o" ]

Array.from() 将类数组转化为数组

类数组中要写属性length,类数组里边都有length属性

    let a={
        0:"a",
        1:"a",
        2:"a",
        3:"a",
        "length":4  需要写length属性
    }
    console.log(Array.from(a));   //["a", "a", "a", "a"]
 console.log(Array.from(document.querySelectorAll(".btn")));

Array.of() 将一组值转化为数组

Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
Array.of(3).length // 1

④数组实例的 find()findIndex()

find() 只会返回第一个符合条件的值。
如果没有符合条件的成员,则返回undefined。

    let a=[1,2,3,4,5];
    console.log(a.find(function (n) {
            return n>2;
    }));
    es6写法
    console.log(a.find(n=>n>2))   3

findIndex() 返回第一个符合条件的数组成员的位置
如果所有成员都不符合条件,则返回-1。

    let a=[1,2,3,4,5];
    console.log(a.findIndex(function (n) {
            return n>2;   2
    }));
    console.log(a.findIndex(n=>n>5));   -1

⑤数组实例的 fill() 填充

用值来填充数组

	['a', 'b', 'c'].fill(7)
	// [7, 7, 7]

	new Array(3).fill(7)
	// [7, 7, 7]

多个参数,填充的起始位置和终止位置

 	let a=[1,2,3,4,5];
	a.fill("a",1,3);   取小不取大
    console.log(a)   (5) [1, "a", "a", 4, 5]

七.es6对象的扩展

①属性的简写

名字和变量名称相同,简写

	const b = {foo};
	等同于
	const b = {foo: foo};

    let food="apple"
    var obj={
        food
    }
    console.log(obj);//{food: "apple"}

方法的简写

	let birth = '2000/01/01';
	const Person = {
  	name: '张三',

  	//等同于birth: birth
 	 birth,

  	// 等同于hello: function ()...
  	hello() { console.log('我的名字是', this.name); }
};

②get set 访问器 (给对象封装属性)

① 做开发会用到,面试用到的不多,可能会问你get set访问器是干啥的
② 属性的赋值器(setter)和取值器(getter)
③ get要写在set上边
④ 与 try…catch 异常处理代码联合使用
⑤ 底层代码:对象点属性的获取和赋值

es5写法

	let obj = {
		_num: 0,
    }
    Object.defineProperty(obj, "_num", {
       	get: function () {
        //返回值
        console.log("我在返回值");
        return this._num;
     },
     set: function (val) {
         console.log("设置值");
         try {
             if (val) {
             	this._num = val;
             }
             else {
             	throw  new Error("val is no value");
             }
          }
          catch (err) {
             	console.log(err);
          }
	 }
   })
   obj._num=2;

es6写法

            let obj = {
                get names() {
                    console.log("返回值");
                    return this.name;
                },
                set names(val) {
                    console.log("设置值");
                    try {
                        if (val) {
                            this.name = val;
                        }
                        else {
                            throw  new Error("val is no value");
                        }
                    }
                    catch (err) {
                        console.log(err);
                    }
                }
            }
            obj.names="张三";
            console.log(obj.names);

③super关键字

this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象。

    const popinfo = {
        hello: "bar"
    };
    const world = {
        hello:"my",
        gethello(){
            //获取到原型链上的hello
            //super.hello  指的是world 原型链上的hello
            return super.hello;
        }
    }

    Object.setPrototypeOf(world, popinfo);注意括号中的前后顺序
    console.log(world.gethello());   //bar

super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。

// 报错
const obj = {
  foo: super.foo
}

// 报错
const obj = {
  foo: () => super.foo
}

// 报错
const obj = {
  foo: function () {
    return super.foo
  }
}

④对象的扩展运算符

    let {a,...b}={a:23,x:1,y:2};
    console.log(a,b);  //23 {x:1,y:2}

扩展运算符加解构赋值

由于解构赋值要求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象。

	let { ...z } = null; // 运行时错误
	let { ...z } = undefined; // 运行时错误

例1:解构赋值的拷贝是浅拷贝
即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。

	let obj = { a: { b: 1 } };
	let { ...x } = obj;
	obj.a.b = 2;
	x.a.b // 2

例2:

    let a=[{m:1},2,3];
    let b= [...a];  
    b[0].m=2;
    console.log(a);

八.Set和Map 集合(记方法)

①Set集合里边的值是唯一的

① 可以运用于数组去重(注意Set中的s要大写)
② 每次使用 new一下Set就可以了
③ add方法:给set集合追加值
④ 输出的s 为类数组集合形式,可以用扩展运算符将其转化为数组

 	let arr=[1,2,1,2,3,3,4,4];
 	直接赋值
    let s=new Set(arr);
    间接赋值
    for(let key of arr){
        s.add(key);
    }
    console.log(s);  //Set(4) {1, 2, 3, 4} 最后出来的结果都是一样的
    console.log([...s]);   //(4) [1, 2, 3, 4]

Set的属性和方法

delete() 返回值为布尔值 true false

    let arr=[1,2,1,2,3,3,4,4];
    let s=new Set(arr);
    console.log(s.delete(5));//false
    console.log(s.delete(2));//true
    console.log(s);      //Set(3) {1, 3, 4}

has() 判断是否有那个值 返回值为true false

    let arr=[1,2,1,2,3,3,4,4];
    let s=new Set(arr);
    console.log(s.has(5));//false
    console.log(s.has(2));//true

clear() 清除集合所有元素

    let arr=[1,2,1,2,3,3,4,4];
    let s=new Set(arr);
    s.clear();
    console.log(s);  //Set(0) {}

keys()values()entries()这三个只是提供了遍历方法

Set.prototype.keys():返回键名的遍历器
Set.prototype.values():返回键值的遍历器
Set.prototype.entries():返回键值对的遍历器
keys方法、values方法、entries方法返回的都是遍历器对象。
由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {
  console.log(item);
  返回值的类型是对象
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

② Map 键值对集合

注意m是大写
① map要与set,get方法结合使用
set() 设置键和键值
get() 通过键读取键值
② has(),和delete() 方法返回值为true false
③ clear() 清空集合
④ size 不加括号,返回值为长度
⑤ keys(),values(),entries()在map方法中因为键和键值都有,所以这三个方法的返回值都不同于set方法

    var m=new Map();
    
    m.set("1",{name:"123"});
    console.log(m.get("1"));  //{name: "123"}
    
    console.log(m.has("1"));
    console.log(m.delete("1"));
    console.log(m.size);  //1
	m.clear();
    console.log(m);//Map(0) {}

    console.log(m.keys());
    console.log(m.entries());
    console.log(m.values());

	for(let key of m.keys()){
        console.log(key);  //2
    }
    for(let key of m.values()){
        console.log(key);  //{name: "456"}
    }
    for(let key of m.entries()){
        console.log(key);  //2) ["2", {…}]0: "2"1: {name: "456"}length: 2__proto__: Array(0)
    }

③ JSON转map

先遍历获取到键,再通过键去取值,

 		let op = {
                "name": "张三",
                "sex": "男"
            }
            let m1 = new Map();
            for (let key of Object.keys(op)) {
                m1.set(key, op[key]);
            }
            console.log(m1.entries()); //加entries之后获取出来的是键值对

map集合转JSON

 		let json = {};
            for (let item of m1.keys()) {
                console.log(item);
                json[item] = m1.get(item)
            }
            console.log(json);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值