• ES6-18:class类及其继承


    JavaScript作为一个动态语言,很大程度上的诟病就是缺少了面向对象的这个概念,ES5传统的方法是通过构造函数来实现类的特性;ES6引入了类这一概念,将Class这个概念作为对象的模板,通过关键字class可以定义类;本质上ES6中引入的类是一个语法糖,其大部分功能ES5均可实现;

    JavaScript语言可以实现继承的特征,但ES5与ES6在实现的机制上确迥然不同:

    • ES5继承的实质:先创造子类的实例对象this,然后将父类的方法添加到this上面,及Parent.apply(this);
    • ES6继承的实质:先创造父类的实例对象this,然后再用子类的构造函数修改 this,因此ES6子类继承必须先调用super方法;

    1.类与对象的区别

    1. 先来看一下对象和类的定义
    ②对象,是一个具体的个体,拥有对象名、属性、方法三个特征;每个对象拥有自己独立的属性,依靠属性来区分不同的对象,方法是对象的动态属性,也成为方法/服务;每个方法用来确定对象的一种行为或功能;   
    ①类,是抽象的概念集合,拥有类标识、属性、方法三个特征,是一类具有相同特性的个体的抽象和归纳;类是抽象出能反映与当前目标有关的本质特征,忽略那些与当前目标无关的非本质特征,从而找出事物的共性,把具有共同性质的事物归结为一类,进而抽象出的概念;
    

    类的变量:一个类所包含的变量根据其可访问性的差别分为:①局部变量:定义在方法、构造方法、语句块中的变量,方法结束后变量就自动销毁;②成员变量:定义在类中,方法体之外的变量,可被类中的方法、构造方法、语句块访问;③成员变量:定义在类中,方法体之外,且用static修饰的变量;

    类的修饰符:类的变量修饰符有4种:publicprivateprotectedfriendly;类的方法有7种修饰符:publicprivateprotectedstaticabstractfinalsynchronized;其区别如下:

    • public:在类中任意地方可见、对子类可见、对继承对象可见;
    • private:在类中任意地方可见、在类外不可见;
    • protected:在类中任意地方可见、在类外不可见,不可被外部修改

    类和对象都是面向对象程序设计的基本组成单元,但两者又有所不同,简单来说:
    两者之间的主要区别如下:

    • 类是对象的模板,对象是类的实例;
    • 类不能直接使用,只有通过对象才可使用,而对象可以直接使用;
    • 类需要在对象之前创建,对象可以继承类;
    • 类和对象都具有一系列属性(静态属性)、方法(动态属性/服务/操作);

    2. ES6 类的特性

    • 类的数据类型就是函数,类本身指向构造函数;
    • 类具有构造方法constructor(),类内部this指向实例对象;
    • 类的所有方法都定义在类的prototype属性上,类方法的调用其调用实质上就是调用原型上的方法;
    • 类内部定义的所有方法都是不可枚举的;而ES5原型上的所有方法都是可以枚举的;
    • 类的属性名可以采用表达式;
    • 类和模块内部默认使用严格模式;
    • 类的方法之间不需要逗号分隔,加了会报错;
    • 类必须用new来调用,否则会报错;
    • 类的实例化对象必须使用new,否则会报错;
    • 类中变量的定义不存在变量提升,这一点是为了保证子类继承必须在父类之后定义
    // 案例1:类的创建
    class Person{};      // 类声名方式
    class Cat=class cat{};// 表达式方式
    
    // 案例2
    class Person1{
        constructor(name,age){
            this.name=name;
            this.age=age;
        }
        sayHi(){
            console.log('My name is'+this.name+'; and I'm '+this.age);
        }
    }
    Person1===Person1.prototype.constructor;//true
    // 以上写法和下面写法本质上一样
    class Person2{
        constructor(name,age){
            this.name=name;
            this.age=age;
        }
    };
    Person2.prototype.sayHi=function(){
        console.log('My name is'+this.name+'; and I'm '+this.age);
    }
    // 或
    class Person2{
        constructor(name,age){
            this.name=name;
            this.age=age;
        }
    };
    Person2.prototype={
        sayHi(){
            console.log('My name is'+this.name+'; and I'm '+this.age);
        }
    }
    
    

    3. ES6类的私有属性、私有方法

    ES6并没有提供类的私有属性、私有方法特性,所以私有属性、私有方法都需要通过其他方法模拟实现;

    • 私有属性实现:私有属性提案属性前加#
    class Piont{
        #x
        cnstructor(x=0){
            #x=x*2;
        }
    }
    
    • 私有方法实现:利用Symbol+表达式方法名;
    const foo=Symbol('foo');
    export default class Cat{
        bar(){console.log('这是一个公有方法')}
        [foo](){console.log('这是一个私有方法)}
    }
    

    4. ES6类中静态属性、静态方法

    类是实例的原型,所有类中的方法和属性都会被实例继承,而静态属性、静态方法不会被实例继承,可以被子类继承,并且通过直接调用;类中的静态属性、静态方法在类中都采用static关键字;此外静态属性和静态方法还可以在类外部定义

    // 示例1 关键字stativc定义静态属性、静态方法
    class Foo{
        name=1;
        static age=2;
        sayMethod(){console.log('这是一个公有方法')}
        static say(){console.log('这是一个私有方法')}  
    }
    let foo=new Foo();
    class Bar extends Foo{};
    
    
    consle.log(foo.name);//1
    consle.log(foo.age);// Type Error foo.age is undefined
    Foo.say(); // 这是一个私有方法
    bar.say();  // 这是一个私有方法
    foo.sayMethod(); // 这是一个公有方法
    foo.say();   // TyoeError: foo.say is not a function
    
    

    5. Class.name 、new.target属性

    • name属性:返回一个类的标识;
    • target属性:返回new命令所用的构造函数,而子类继承父类,是new.target返回子类;该属性可用于确定构造函数是如何调用的;
    // name属性
    class Foo{};
    console.og(foo.name);//Foo
    // target属性
    class Person{
        constructor(age,name){
            this.age=age;
            this.width=name;
            console.log(new.target===Person);
        }
    }
    var obj=new Person(13,'John');// true
    var obj0=Person.call(obj,(24,'Lilly'));//false
    class Person1 extends Person{
        constructor(age,name){
            super(age,name);
        }
    }
    let obj1=new Person1(23,'Jim');// false
    

    6. ES6类的继承

    参考:

  • 相关阅读:
    react的路由以及传值方法
    三连击
    给网页添加鼠标样式
    单词统计(续)
    个人课程总结
    构建之法阅读笔记02
    构建之法阅读笔记01
    第十六周总结
    计算最长英语单词链
    第十五周总结
  • 原文地址:https://www.cnblogs.com/hbzyin/p/ES6.html
Copyright © 2020-2023  润新知