ES6总结(四)

1. 类

  1. JavaScript和Java关于类的区别
    首先需要清楚JavaScript是基于原型的(连接),而Java是基于的(复制)。
  2. 类的声明
    类声明是以class关键字开始的,然后是类的名字,剩余部分像是对象字面量的简写。
    下面来看看JavaScript是如何定义使用类的,如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Dog{
    // 构造函数使用constructor来定义
    constructor(name,age){
    this.name = name;
    this.age = age;
    }
    bark(){
    console.log(`我叫${this.name}`);
    }
    }
    const lili = new Dog('lili',2);
    上面这段代码等价于我们在没有使用ES6之前来定义类的一种写法,如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    function Dog(name,age){
    this.name = name;
    this.age = age;
    }
    Dog.prototype.bark = function(){
    console.log(`我叫${this.name}`);
    }
    const lili = new Dog('lili',2);
  3. 类语法注意事项
    a. 类声明不会被提升;
    b. 类声明中的代码都自动运行在严格模式下
    c. 调用类必须使用new;
    d. 类中所有方法都是不可枚举的。
    对于d这一点,我举一个简单的例子,就拿上面的两段代码来说,第一段代码是使用class来定义的类,使用的是ES6中的语法,此时我们来枚举一下它的属性,如下所示:(此时我们会发现bark方法并没有枚举出来)
    1
    2
    3
    for(var prop in lili){
    console.log(prop); // name age
    }
    如果我们使用的是function来定义类,即ES6之前的语法,然后我们再来枚举它的属性,将会得到不同的结果,如下所示:(此时我们会发现bark方法被枚举出来了)
    1
    2
    3
    for(var prop in lili){
    console.log(prop); // name age bark
    }
    e. 类中的方法是不能用new调用的;
    f. 在类的方法中重写类名报错
  4. 写”use strict”表明下面代码都是使用严格模式
  5. 类的表达式
    如下所示:
    1
    2
    3
    4
    5
    6
    const Cat = class{ // 类表达式
    constructor(age){
    this.age = age;
    }
    }
    const a = new Cat(1);
  6. 类为一等公民
    a. 可以作为参数传给函数;
    b. 能作为函数返回值;
    c. 能给变量赋值。
  7. 静态成员
    一般来说都是静态方法(static)。
    什么是静态方法?类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
    总结一下:通过”构造函数.“的这种形式就叫静态方法。
    下面给大家举一个例子,如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    class Foo{
    static classMethod(){ // 静态方法
    return "hello";
    }
    }
    Foo.classMethod(); // 正确调用,打印出hello
    var foo = new Foo();
    foo.classMethod(); // 错误调用,报错

2. 类的继承

  1. ES6中class继承extends以及super的使用。我们需要注意静态方法的继承,子类会继承父类的静态方法。
    举一个例子,如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    class Foo{
    static classMethod(){
    return 'hello';
    }
    }
    class Bar extends Foo{} // Bar继承Foo
    // 其原因就是因为父类的静态方法,可以被子类继承
    Bar.classMethod(); // 'hello'
  2. 静态方法也是可以从super对象上调用的
    下面给大家举一个例子,如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Foo{
    static classMethod(){
    return 'hello';
    }
    }
    class Bar extends Foo{
    static classMethod(){
    return super.classMethod() + ',too';
    }
    }
    Bar.classMethod(); // 'hello,too'
  3. 重点:关于new做的事情?
    new做的一件事就是改变this指向,会创建一个新对象,然后this指向这个新对象。子类比较特殊,你new他的时候,如果不执行super方法,this就不会指向一个新对象。必须要执行super,然后创建一个新对象,让this指向他,先去父亲那逛一圈,然后回来。
    对于上面说了那么大一段话,我来总结一下,就一句话:子类,你new他this不会指向任何东西,只有你调用super的时候,才创建一个新对象,然后this指向他。

3. 模块化

  1. 在ES5标准之前是没有模块化的
  2. 在这里立即执行函数去写一个模块的问题:
    a. 没有完全解决全局变量污染;
    举一个例子,如下所示:
    在add.js文件中写入:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (function(){
    function show(){
    console.log(111);
    }
    function add(a,b){
    show();
    return a + b;
    }
    window.add = add;
    })()
    b. 我们需要考虑script标签加载顺序。
  3. 在node.js环境中,js文件之间是没有关系的,也就是说每个js都是一个独立的作用域
  4. es6当中只是定义了语法,但是没有定义我们的加载顺序
    不直接去使用es6模块化,因为:a. 浏览器兼容性问题;b. 没有定义我们的加载方式。
  5. 模块化的定义和写法

注意:如果你想引入模块的话,需要将所有东西放到服务器上。
服务器下载:window可以下载一个wamp软件,mac可以下载一个mamp软件。
举一个例子,如下所示:

1
2
3
4
5
6
7
// type="text/javascript"表示共享一个全局作用域
// type="module"表示你引入的是模块
// 注意:此时我们应该开一个服务器

// 在这里面可以引入内容,如
// import {add} from "./add.js"