• 0. ES6的入门用法


    本节内容:

      一 、let 命令

        1.1 let基本特点

        1.2 let 变量的作用域

        1.3  不存在变量提升

        1.4 不允许重复声明

        1.5 let声明全局变量

      二、const 命令

        2.1 const命令的特点

      三、es5和es6的函数对比

        3.1 ES5函数的写法

        3.2 ES6函数的写法

      四、自定义对象中封装函数的写法

        4.1  this的指向问题

        4.2  es5对象中封装函数的方法

        4.3  es6对象中封装函数的方法

          4.4. 函数写法的单体模式

      五、es5和es6的类写法对比

        5.1 es5类写法

        5.2  es6的类写法

    一 、let 命令

    1、 let基本特点

    特点:
      1.a是局部作用域的function xx(){let a = 'xxoo';} if(){let a = 'ss';}
      2.不存在变量提升
      3.不能重复声明(var可以重复声明变量)
      4 let声明的全局变量不从属于window对象,var声明的全局变量从属于window对象。

    2 、let变量的作用域

    ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效

    {
      let a = 10;
      var b = 1;
    }
    a // ReferenceError: a is not defined.
    b // 1

    上面代码在代码块之中,分别用letvar声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,

    var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。

    例如 :for循环的计数器,就很合适使用let命令。

    for (let i = 0; i < 10; i++) {}
    console.log(i);
    //ReferenceError: i is not defined
    //计数器i只在for循环体内有效,在循环体外引用就会报错

    下面的代码如果使用var,最后输出的是10。

    var a = [];
    for (var i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 10

    上面代码中,变量ivar声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值。

    如果使用let,声明的变量仅在块级作用域内有效,最后输出的是6

    var a = [];
    for (let i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 6

    上面代码中,变量ilet声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。

    3、不存在变量提升

    在js中只有两种作用域,全局作用域和函数作用域,在ES6之前,js是没有块级作用域。

    JavaScript 仅提升声明,而不提升初始化。如果你先使用的变量,再声明并初始化它,变量的值将是 undefined。

    1:所有的声明都会提升到作用域的最顶上去。

    2:同一个变量只会声明一次,其他的会被忽略掉。

    3:函数声明的优先级高于变量申明的优先级,并且函数声明和函数定义的部分一起被提升

    函数提升的例子:

    catName("Chloe");// 即使在声明之前调用依然可以执行,不会报错
    
    function catName(name) {
        console.log("我的猫名叫 " + name);
    }

    let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。

    console.log(foo); // 输出undefined
    console.log(bar); // 报错ReferenceError
    var foo = 2;
    let bar = 2;

    上面代码中,变量foovar命令声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined

    变量barlet命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误

    在定义的函数名字和变量名相同的情况下,函数提升优先级高于变量的例子

    func(); // 1
    var func;
    function func() {
      console.log(1);
    }
    func = function() {
      console.log(2);
    }

    牢记这三点:

    只有声明本身会被提升,而赋值操作不会被提升。

    变量会提升到其所在函数的最上面,而不是整个程序的最上面。

    函数声明会被提升,但函数表达式不会被提升。

    4、不允许重复声明

    let不允许在相同作用域内,重复声明同一个变量。

    // 报错
    function () {
      let a = 10;
      var a = 1;
    }
    
    // 报错
    function () {
      let a = 10;
      let a = 1;
    }

    因此,不能在函数内部重新声明参数。

    function func(arg) {
      let arg; // 报错
    }
    
    function func(arg) {
      {
        let arg; // 不报错
      }
    }

    5、let声明的全局变量

    ES5声明变量只有两种方式:var和function。
    ES6有let、const、import、class再加上ES5的var、function共有六种声明变量的方式。
    还需要了解顶层对象:浏览器环境中顶层对象是window.
    ES5中,顶层对象的属性等价于全局变量。var a = 10; window.a
    ES6中,有所改变:var、function声明的全局变量,依然是顶层对象的属性;let、const、class声明的全局变量不属于顶层对象的属性,

    也就是说ES6开始,全局变量和顶层对象的属性开始分离、脱钩,目的是以防声明的全局变量将window对象的属性造成污染,

    因为window对象是顶层对象,它里面的属性是各个js程序中都可以使用的,不利于模块化开发,

    并且window对象有很多的自有属性,也为了防止对window的自由属性的污染,所以在ES6中将顶层对象和全局变量进行隔离。

    var a = 1;
    console.info(window.a);  // 2
            
    let b = 2;
    console.info(window.b); //undefined

    二 、const 命令

    1、基本特点

    基本上和let一致,只有const是不可改变的量

    特点:   1.局部作用域 

        2.不存在变量提升 

        3.不能重复声明 

        4.一般声明不可变的量

    三 、es5和es6的函数对比

    1、ES5函数的写法

    //ES5写法
    function add(x){
        return x
        }
    add(
    5); //匿名函数 var add = function (x) { return x }; add(5);

    2、ES6函数的写法

        //ES6的匿名函数
        let add = function (x) {
            return x
        };
        add(5);
            
        //ES6的箭头函数,就是上面方法的简写形式
        let add = (x) => {
            return x
        };
        console.log(add(20));
        //更简单的写法,但不是很易阅读
        let add = x => x;
        console.log(add(5));
        多个参数的时候必须加括号,函数返回值还是只能有一个,没有参数的,必须写一个()
        let add = (x,y) => x+y;

    四、自定义对象中封装函数的写法

    定义:js中自定义对象相当于Python中的字典

    1、this的指向问题

    $(xx).click(function(){
        this -- 绑定事件的DOM标签对象
    })
    document.getElementById('d1').onclick = function(){this.innerText;};
     

    2、es5对象中封装函数的方法

    1、匿名函数的this指向

     var name = '子俊';
        var person1 = {
            name:'超',
            age:18,
            f1:function () {  //在自定义的对象中放函数的方法
                console.log(this);//this指向的是当前的对象,{name: "超", age: 18, f1: ƒ}
                console.log(this.name)  // '超'
            }
        };
        person1.f1();  //通过自定对象来使用函数,谁调用this就指向谁

    2、箭头函数的this指向

     var name = '子俊';
        var person1 = {
            name:'超',
            age:18,
            f1:() => {  //在自定义的对象中放函数的方法
                console.log(this);
        //this指向的不再是当前的对象了,而是指向了person1的父级对象(称为上下文),而此时的父级对象是我们的window对象,Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
                console.log(this.name)  // '子俊'
            }
        };
        person1.f1();  

    3、es6对象中封装函数的方法

    1、匿名函数的this指向

    let name = '子俊';
        let person1 = {
            name:'超',
            age:18,
         f1:
    function () { //在自定义的对象中放函数的方法 console.log(this);//this指向的是当前的对象,{name: "超", age: 18, f1: ƒ} console.log(this.name) // '超' } }; person1.f1(); //通过自定对象来使用函数

    2、箭头函数的this指向

    let name1 = '子俊';
        let person1 = {
            name1:'超',
            age:18,
            f1: () => {  //在自定义的对象中放函数的方法
                console.log(this);//this指向的不再是当前的对象了,而是指向了person的父级对象(称为上下文),而此时的父级对象是我们的window对象,Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
                console.log(this.name1)  // 'undefined'  // 由于外层的name1 不属于window对象
            }
        };
        person1.f1();  

    3. 函数写法的单体模式

    let name = '子俊';
        let person1 = {
            name:'超',
            age:18,
        
       //可以写成 f1(){} 相当于 f1:function(){}
            f1:function () {  //在自定义的对象中放函数的方法
                console.log(this);//this指向的是当前的对象,{name: "超", age: 18, f1: ƒ}
                console.log(this.name)  // '超'
            }
        };
        person1.f1();  //通过自定对象来使用函数

    五、es5和es6的类写法对比

    1、es5类写法

    <script>
        //es5写类的方式
        
        function Person(name,age) {
            //封装属性
            this.name = name;  //this--Python的self
            this.age = age;
        }
    
        //在类中不能封装方法
        //封装方法,原型链
        Person.prototype.f1 = function () {
            console.log(this.name);//this指的是Person对象, 结果:'超'
        };
        //封装方法,箭头函数的形式写匿名函数
        Person.prototype.f2 = ()=>{
            console.log(this); //Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}  this指向的是window对象
        };
    
        var p1 = new Person('超',18);
        p1.age
        
        p1.f1();
        p1.f2(); 
        //其实在es5我们将js的基本语法的时候,没有将类的继承,但是也是可以继承的,还记得吗,那么你想,继承之后,我们是不是可以通过子类实例化的对象调用父类的方法啊,当然是可以的,知道一下就行了,我们下面来看看es6里面的类怎么写
    </script>

    2、es6类写法

     <script>
    class Person2{
            constructor(name,age){ //对象里面的单体模式,记得上面将函数的时候的单体模式吗,这个方法类似于python的__init__()构造方法,写参数的时候也可以写关键字参数 constructor(name='超2',age=18)
                //封装属性
                this.name = name;
                this.age = age;
            }  //注意这里不能写逗号
            
            showname(){  //封装方法
                console.log(this.name);
            }  //不能写逗号
            showage(){
                console.log(this.age);
            }
        }
        let p2 = new Person2('超2',18);
        p2.showname()  //调用方法  '超2'
        //es6的类也是可以继承的,这里咱们就不做细讲了,将来你需要的时候,就去学一下吧,哈哈,我记得是用的extends和super
    
    </script>
  • 相关阅读:
    I/O会一直占用CPU吗?【转载】
    CPU和线程的关系
    future封装了callable,thread封装future。
    (转)Java中的守护线程
    线程中sleep方法和wait方法有什么区别?(转)
    Java异常---获取异常的堆栈信息
    分析iOS Crash文件,使用命令符号化iOS Crash文件
    String Matching(poj1580)
    U转串口驱动安装
    [LNU.Machine Learning.Question.1]梯度下降方法的一些理解
  • 原文地址:https://www.cnblogs.com/yj0405/p/14561120.html
Copyright © 2020-2023  润新知