3.04.20ES6

3.04.20 ES6

1.ES6概念

  • ES6 是JavaScript的第六个版本,ES是ECMA Script的缩写,是2015年发布的。
  • ES6另外一个名称 ECMAScript2015,也包括ES7/8/9的内容。javascript可以做前端的工作,也可以做后端的工作(Nodejs)。
  • javascript是弱类型的编程语言,随着脚本语言技术不断发展,市场需求增加,在开发环境中需要的语法要求越来越严格。目前在web开发环境中,出现了typescript。可以弥补一些JS的不足。
  • ES5的语法比较自由,存在一些不合理的地方。ES6的出现是为了更好的去规范脚本语言,去弥补ES5存在的先天不足,比如:变量重复声明 不报错提示;变量声明提升,只是undefined;没有块作用域的概念。

2.声明变量的关键字let

  • let 关键字 声明的变量 不能重复声明
  • let 关键字 声明的变量 没有变量声明提升
  • let 关键字 声明的变量 有块级作用域
  • 例如:
<script>
    // 1.不能重复声明
    var a ="aaa";
    var a="bbb";
    console.log(a);

    let b ="111";
    //let b ="222"; //控制台报错:ncaught SyntaxError: Identifier 'b' has already been declared
    console.log(b); 

    //2.没有变量名提升
    console.log(box); //undefined
    var box="box";

    //console.log(box2);
    let box2="box2";//控制台报错:Uncaught ReferenceError: Cannot access 'box2' before initialization

    //3.有块级作用域
    for(var i=0;i<2;i++){

    }
    console.log(i);

    for(let j=0;j<2;j++){

    }
    console.log(j);//控制台报错:Uncaught ReferenceError: j is not defined
    
    var a=1;
    if(a==1){
        let b=3;
        var d=4;
    }
    // console.log(b);//报错
    console.log(d); //4

</script>   

3.const关键字

  • const 关键字 声明的变量 不能重复声明
  • const 关键字 声明的变量 没有变量声明提升
  • const 关键字 声明的变量 有块级作用域
  • const 关键字 声明的变量 是常量,不允许修改
  • 例如:
    // 1.不能重复声明
    var a ="aaa";
    var a="bbb";
    console.log(a);

    const x ="111";
    //const x ="222"; //控制台报错:Uncaught SyntaxError: Identifier 'x' has already been declared
    console.log(x);

    //2.没有变量名提升
    console.log(box); //undefined
    var box="box";

    //console.log(box22);
    const box22="box2";//控制台报错:Uncaught ReferenceError: Cannot access 'box22' before initialization

    //3.有块级作用域
    for(var i=0;i<2;i++){
        var p=0;
    }
    console.log(p);

    for(var j=0;j<2;j++){
        const k=0;
    }
    //console.log(k);//控制台报错:Uncaught ReferenceError: k is not defined

    //4.是常量,不允许修改
    let cbox="1111";
    cbox="22222";
    console.log(cbox);

    const cbox2="aaaa";
    //cbox2="bbbb"; //报错提示:Uncaught TypeError: Assignment to constant variable.
    console.log(cbox2);

    const URL = "127.0.0.1:3000";
    // 报错提示:Uncaught TypeError: Assignment to constant variable.
    // 常量的值不允许修改
    // if(URL = "127.0.0.1:8080"){
    //     console.log("进入判断,执行代码");
    // }
    //用于写进判断语句的变量可以用const声明,避免造成赋值的情况

    //当const是引用数据类型时,需要注意,他依然是没有修改arr的值,arr的值依然是同一个地址:
    const arr=[1,2,3,4];
    arr[0]=99;
    console.log(arr);

4.认识块级作用域

  • 任何一对花括号({})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。
  • 同一案例,两种不同写法,理解ES6中let关键字配合循环会产生多个块级作用域的效果:
  • ES5写法:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .btn {
            border: 1px solid #ccc;
            padding: 15px 20px;
            cursor: pointer;
        }
        .btn.active {
            background-color: red;
            color: #fff;
        }
    </style>
</head>
<body>
    <h3 class="txt">点击了第<span>x</span>个按钮</h3>
    <button class="btn">按钮1</button>
    <button class="btn">按钮2</button>
    <button class="btn">按钮3</button>
    <button class="btn">按钮4</button>
    <button class="btn">按钮5</button>
    <button class="btn">按钮6</button>

    <script>
        // 需求:
            // 给按钮绑定点击事件,第三个按钮不绑定点击事件
            // 所点击的按钮添加背景高亮
            // 不是当前点击的按钮背景不高亮
            //

        // ES5
        // 想获取当前点击标签的索引值
            // 1、闭包
            // 2、自定义属性 (或者属性绑定)
        var elements = document.querySelectorAll(".btn");
        var span = document.querySelector(".txt span");
        for(var i = 0 ; i < 6 ; i ++){
            ;(function(index){
                elements[i].onclick = function(){
                    span.innerHTML = (index + 1);
                    // 排他思想
                    for(var j = 0 ; j < elements.length ; j ++){
                        elements[j].className = "btn";
                    }   
                    // 当前点击的按钮
                    this.className = "btn active";
                }
            })(i)
        }

    </script>
</body>
</html>
  • ES6写法:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .btn {
            border: 1px solid #ccc;
            padding: 15px 20px;
            cursor: pointer;
        }
        .btn.active {
            background-color: red;
            color: #fff;
        }
    </style>
</head>
<body>
    <h3 class="txt">点击了第<span>x</span>个按钮</h3>
    <button class="btn">按钮1</button>
    <button class="btn">按钮2</button>
    <button class="btn">按钮3</button>
    <button class="btn">按钮4</button>
    <button class="btn">按钮5</button>
    <button class="btn">按钮6</button>

    <script>
        // 需求:
            // 给按钮绑定点击事件,第三个按钮不绑定点击事件
            // 所点击的按钮添加背景高亮
            // 不是当前点击的按钮背景不高亮
            //

        //ES6:
        var buttons = document.querySelectorAll(".btn");
        var span = document.querySelector(".txt span");
        // {} 块作用域
        // 注意此处的关键字不是var ,是let关键字
        // 可以不使用闭包,获取当前点击标签的索引值
        // 每循环一次,就产生一个块作用域
        for(let i = 0 ;i < buttons.length ; i ++) {
            buttons[i].onclick = function(){
                span.innerHTML = (i + 1);
                // 排他思想
                for(let j = 0 ; j < buttons.length ; j ++ ){
                    buttons[j].className = "btn";
                }
                // 给当前点击的标签设置背景高亮
                this.className = "btn active";
            }
        }

    </script>
</body>
</html>  

5.模板字符串

  • 模板字符串是ES6拼接字符串的一种特定写法
  • 语法:
    var a="带拼接的变量";
    var str=`字符串${a}字符串`;
    //等价于
    var str='字符串'+a+'字符串';
  • 注意:字符串是用(``)包住,且变量用${}的方式包住。

6.了解严格模式

  • 介绍:ECMAScript 5的严格模式是采用具有限制性JavaScript变体的一种方式,从而使代码显示地脱离"马虎模式/稀松模式/懒散模式"模式。
    • 严格模式对正常的 JavaScript语义做了一些更改。
    • 严格模式通过抛出错误来消除了一些原有静默错误。
    • 严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快。
    • 严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
  • 严格模式存在的一些意义:
    • 为未来的ECMAScript版本铺平道路
    • 严格模式下更容易写出“安全”的JavaScript。现在有些网站提供了方式给用户编写能够被网站其他用户执行的JavaScript代码。在浏览器环境下,JavaScript能够获取用户的隐私信息,因此这类Javascript必须在运行前部分被转换成需要申请访问禁用功能的权限。没有很多的执行时检查的情况,Javascript的灵活性让它无法有效率地做这件事。一些语言中的函数普遍出现,以至于执行时检查他们会引起严重的性能损耗。做一些在严格模式下发生的小改动,要求用户提交的JavaScript开启严格模式并且用特定的方式调用,就会大大减少在执行时进行检查的必要。
    • 严格模式让arguments和eval少了一些奇怪的行为。两者在通常的代码中都包含了很多奇怪的行为: eval会添加删除绑定,改变绑定好的值,还会通过用它索引过的属性给形参取别名的方式修改形参. 虽然在未来的ECMAScript版本解决这个问题之前,是不会有补丁来完全修复这个问题,但严格模式下将eval和arguments作为关键字对于此问题的解决是很有帮助的。
  • 为脚本开启严格模式
    • 语法:为整个脚本文件开启严格模式,需要在所有语句之前放一个特定语句 “use strict”; (或 ‘use strict’;)

7.解构赋值

  • 解构赋值:在左右两侧的数据结构相同的情况下,可以把右侧的数据复制给左侧的变量

1.数组解构赋值

  • 语法:
    let [x,y,z]=[1,2,3];
    console.log(x,y,z); //1 2 3

    var [[a],[b],[c]]=[[4],[5],[6]];
    console.log(a,b,c); //4,5,6

    var res=[
        {name:"小明",age:20},
        {name:"小红",age:21},
        {name:"小刚",age:22}
    ]

    var [one]=res;
    console.log(one); //{name:"小明",age:20}

    var [,two]=res;
    console.log(two);//{name: '小红', age: 21}

2.对象解构赋值

  • 语法:
    var obj={
        id:"123",
        pass:"456",
        user:"小宽",
        arr:[
            {name:"小红",age:21},
            {name:"小刚",age:22}
        ]
    }
    var {user,pass}=obj;

    console.log(user); //小宽
    console.log(pass);//456

    var [,two]=obj.arr;
    console.log(two); //{name: '小刚', age: 22}

    var{arr}=obj;
    console.log(arr);//[{name:"小红",age:21},{name:"小刚",age:22}]

    var{arr:[,tow2]}=obj;
    console.log(two); //{name: '小刚', age: 22}

    var{arr:[,{name,age}]}=obj;
    console.log(name,age); //小刚 22

8.箭头函数

1. 概念

  • 箭头函数:是一种语法更为简约的函数编写方式,箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。

2. 语法

  1. () => {}
  2. () => 表达式
  3. 有且只有一个参数时,可以省略() singleParam => {}
  4. ES5中函数的写法转换成箭头函数
  • 使用关键字声明
    //该方式声明的函数 转不了 箭头函数
    function 函数名(参数的数据类型类型:参数值){
    }

    //匿名函数
    function(){}

    //转箭头函数:
    ()=>{}
  • 使用函数表达式来声明函数
    var 变量名 = function ([参数列表]){
     // 这里放函数体,函数体就是要重复执行代码块  
    }

    //转箭头函数
    var 变量名=([参数列表])=>{
        // 这里放函数体,函数体就是要重复执行代码块 
    }
  • 构造函数声明函数
    var func = new Function ("参数1,参数2","functionBody")
    //该方式声明的函数 转不了 箭头函数

3. 箭头函数的注意点

  1. 没有单独的this,箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this
    function Person(){
    this.age = 0;

    setInterval(() => {
        this.age++; // |this| 正确地指向 p 实例
    }, 1000);
    }

    var p = new Person();
  1. 通过 call 或 apply 调用时,由于箭头函数没有自己的this指针,通过 call() 或 apply() 方法调用一个箭头函数时,不能绑定this,不能改变this的指向,他们的第一个参数会被忽略。(这种现象对于bind方法同样成立)。例如:
    var adder = {
    base : 1,

    add : function(a) {
        var f = v => v + this.base;
        return f(a);
    },

    addThruCall: function(a) {
        var f = v => v + this.base;
        var b = {
        base : 2
        };

        return f.call(b, a);
    }
    };

    console.log(adder.add(1));         // 输出 2
    console.log(adder.addThruCall(1)); // 仍然输出 2
  1. 不绑定arguments,箭头函数不绑定Arguments 对象。因此,在本示例中,arguments只是引用了封闭作用域内的arguments:
    var arguments = [1, 2, 3];
    var arr = () => arguments[0];

    arr(); // 1

    function foo(n) {
    var f = () => arguments[0] + n; // 隐式绑定 foo 函数的 arguments 对象. arguments[0] 是 n,即传给foo函数的第一个参数
    return f();
    }

    foo(1); // 2
    foo(2); // 4
    foo(3); // 6
    foo(3,2);//6
  1. 箭头函数不能搭配 使用 new 操作符,箭头函数不能用作构造器,和 new 一起用会抛出错误。
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor
  1. 箭头函数没有prototype属性。
    var Foo = () => {};
    console.log(Foo.prototype); // undefined

4.箭头函数的写法的注意

  1. 函数体
  • 箭头函数可以有一个“简写体”或常见的“块体”。在一个简写体中,只需要一个表达式,并附加一个隐式的返回值。在块体中,必须使用明确的return语句。
    var func = x => x * x;
    // 简写函数 省略return

    var func = (x, y) => { return x + y; };
    //常规编写 明确的返回值
  1. 返回对象字面量
  • 记住用params => {object:literal}这种简单的语法返回对象字面量是行不通的。
    var func = () => { foo: 1 };
    // Calling func() returns undefined!

    var func = () => { foo: function() {} };
    // SyntaxError: function statement requires a name

    //这是因为花括号({} )里面的代码被解析为一系列语句(即 foo 被认为是一个标签,而非对象字面量的组成部分)。
    //所以,记得用圆括号把对象字面量包起来:
    var func = () => ({foo: 1});
  1. 换行
  • 箭头函数在参数和箭头之间不能换行。
    var func = ()
           => 1;
    // SyntaxError: expected expression, got '=>'

    //以下不会报错:
    var func = (a, b, c) =>
    1;

    var func = (a, b, c) => (
    1
    );

    var func = (a, b, c) => {
    return 1
    };

    var func = (
    a,
    b,
    c
    ) => 1;

    // 不会有语法错误

  1. 解析顺序
  • 虽然箭头函数中的箭头不是运算符,但箭头函数具有与常规函数不同的特殊运算符优先级解析规则。
    let callback;

    callback = callback || function() {}; // ok

    callback = callback || () => {};
    // SyntaxError: invalid arrow-function arguments
    //SyntaxError:无效的箭头函数参数

    callback = callback || (() => {});    // ok
  1. 箭头函数内定义的变量及其作用域
    // 常规写法
    var greeting = () => {let now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
    greeting();          //"Good day."
    console.log(now);    // ReferenceError: now is not defined 标准的let作用域

    // 参数括号内定义的变量是局部变量(默认参数)
    var greeting = (now=new Date()) => "Good" + (now.getHours() > 17 ? " evening." : " day.");
    greeting();          //"Good day."
    console.log(now);    // ReferenceError: now is not defined

    // 对比:函数体内{}不使用var定义的变量是全局变量
    var greeting = () => {now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
    greeting();           //"Good day."
    console.log(now);     // Fri Dec 22 2017 10:01:00 GMT+0800 (中国标准时间)

    // 对比:函数体内{} 用var定义的变量是局部变量
    var greeting = () => {var now = new Date(); return ("Good" + ((now.getHours() > 17) ? " evening." : " day."));}
    greeting(); //"Good day."
    console.log(now);    // ReferenceError: now is not defined
  1. 箭头函数也可以使用闭包:
    // 标准的闭包函数
    function A(){
        var i=0;
        return function b(){
                return (++i);
        };
    };

    var v=A();
    v();    //1
    v();    //2


    //箭头函数体的闭包( i=0 是默认参数)
    var Add = (i=0) => {return (() => (++i) )};
    var v = Add();
    v();           //1
    v();           //2

    //因为仅有一个返回,return 及括号()也可以省略
    var Add = (i=0)=> ()=> (++i);
  1. 一种特别的编码方式
    // ES6
        let foo = x => y => r => {
            return {
                x,
                y,
                r
            }
        }
        var obj = foo("110px")("220px")("330px");
        console.log(obj);
    
    // 这种函数的编码方式的函数,称之为柯里化函数
        // 也是闭包的一种体现
        // 换成ES5的代码
        var foo2 = function (x) {
            return function (y) {
                return function (r) {
                    // 书写处理逻辑
                    return {
                        x,
                        y,
                        r
                    }
                }
            }
        }
        var option = foo2("1px")("2px")("3px");
        console.log(option);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值