美文网首页
第三十二节: ES6 Class类

第三十二节: ES6 Class类

作者: 时光如剑 | 来源:发表于2020-11-03 19:10 被阅读0次

    1. ES6 Class 类

    ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

    ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

    1.1 . 复习构造函数

    之前用函数模拟类

    function Person(name,age){
        this.name = name;
        this.age = age; 
    }
    Person.prototype.showName = function(){
        return `我的名字是:${this.name}`;
    }
    Person.prototype.showAge = function(){
        return `我的名字是:${this.age}`;
    }
    
    let p1 = new Person("wuwei",18);
    console.log(p1.showName());
    console.log(p1.showAge());
    

    但是之前讲了一个合并对象的,那么我们可以将新增的方法放在一个对象里合并到原型上

    function Person(name,age){
        this.name = name;
        this.age = age; 
    }
    Object.assign(Person.prototype,{
        showName(){
            return `我的名字是:${this.name}`;
        },
        showAge(){
            return `我的名字是:${this.age}`;
        }
    })
    
    let p1 = new Person("wuwei",18);
    console.log(p1.showName());
    console.log(p1.showAge());
    
    1.2 ES 6 变形的类Class
    // 这是类 不是json 所以里面不需要加逗号
    class Person{
        // 这是一个构造方法(函数),只要new Person() 这个构造函数会自动执行
        constructor(name,age){ 
            console.log(`构造函数执行了,name:${name},age:${age}`) 
        }
        
        //以下是构造函数原型上的方法
        
        showName(){
            return `名字:${this.name}`;
        }    // 不需要加逗号,加逗号就报错
        
        showAge(){
            return `年龄:${this.age}`;
        }
    }
    
    
    // 这个Person也是要给函数,typeof Person  打印function
    let p1 = new Person("wuwei",18);
    console.log(p1.showName());
    console.log(p1.showAge());
    

    表达式的类(不推荐)

    var Person = class {
        constructor(){
            this.name = "wuwei";
        }
        showName(){
            return `名字:${this.name}`
        }
    }
    

    2. constructor

    constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

    class Fn {
    }
    
    // 等同于
    class Fn {
      constructor() {}
    }
    

    constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。

    class Foo {
      constructor() {
        return Object.create(null);
      }
    }
    
    new Foo() instanceof Foo
    // false
    //constructor函数返回一个全新的对象,结果导致实例对象不是Foo类的实例。
    

    3. 类必须使用new调用

    类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

    class Foo {
      constructor() {
        return Object.create(null);
      }
    }
    
    Foo()
    // TypeError: Class constructor Foo cannot be invoked without 'new'
    

    4. 方法名字可以是变量,

    如果要是用变量,那么就要使用[]的表达式

    var aaa = 'wu';
    class Person{
        constructor(name,age){ 
            this.name = name;
            this.age = age;
        }
        [aaa](){
            return `此时属性名是一个变量,就是wu`
        }
    }
    
    // console.log(typeof Person)
    let p1 = new Person("wuwei",18);
    console.log(p1.wu());   // 此时不能通过aaa调用函数,aaa是变量,通过wu调用,可以通过[aaa]调用 p1[aaa]();
    
    

    这里就可以发现属性名可以为表达式

    var aa = 'wu';
    var bb = 'wei';
    
    var obj = {
        [aa + bb]: "无为"
    }
    

    5. ES6 class类没有提升和预解析的功能

    也就是说如果写法会报错

    var p1 = new Person()
    console.log(p1);
    
    class Person{
        constructor(){
            this.name = "aaa"
        }
    }
    
    

    但是以前通过ES5 构造函数模拟类是可以变量提升的,因为本身就是函数

    // 这种写法构造函数会提升,正常打印一个对象
    var p1 = new Person()
    console.log(p1);
    function Person(){
        this.name = "aaa"
    }
    

    6. get set

    取值函数 get 存值函数 set

    class Person{
        constructor(name,age){ 
            this.name = name;
            this.age = age;
        }
        get aa(){
            console.log(`成功获取a的值`)
            return this.age;
        }
        set aa(val){
            console.log(`成功设置a的值为${val}`);
            this.age = val;
        }
    }
    
    var p1 = new Person('wuwei',18)
    

    7.静态方法

    类相当于实例的原型,所有在类中定义的方法,都会被实例继承。

    如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。

    ES6 明确规定,Class 内部只有静态方法,没有静态属性。

    class Person{
        constructor(name,age){ 
            this.name = name;
            this.age = age;
        }
        showName(){
            return `这是通过构造对象调用方法`;
        }
        static aaa(){
            return `这是静态方法,是通过类来调用的方法`;
        }
    }
    
    var p1 = new Person('wuwei',18)
    console.log(p1.showName);
    console.log(Person.aaa());
    

    8. 继承

    子类继承父类

    8.1 之前的子类继承父类
    // 父类
    function Person(name){
        this.name = name;
    }
    Person.prototype.showName = function(){
        return `名字是:${this.name}`;
    }
    
    // 子类
    function Student(name,skill){
        Person.call(this,name);   // 继承父类的属性
        this.skill = skill;
    }
    Student.prototype = new Person; // 继承父类的方法
    
    
    var stu = new Student("wuwei","逃课");
    console.log(stu.name);
    console.log(stu.showName())
    
    8.2 ES6 类的继承 extends
    class Student extends Person{}
    

    这种继承 没法添加自己扩展的属性和方法,添加就报错

    通过super()扩展自己的属性和方法

    // 父类
    class Person{
        constructor(name){
            this.name = name;
        }
        showName(){
            console.log('父类的showName方法');
            return `名字:${this.name}`;
        }
    }
    
    // 子类
    class Student extends Person{
        constructor(name,skill){
            super(name); // 先执行父类的属性,继承后在设置自己的属性
            this.skill = skill;
        }
        // 继承父类的方法同时扩展内容
        showName(){
            super.showName(); // 先执行父类的showName方法
            // 在设置自己的showName方法
            console.log('执行了子类里面的showName');
        }
    
        // 设置自己的方法
        showSkill(){
            return `技能:${this.skill}`
        }
    }
    
    var stu = new Student("wuwei","逃课");
    console.log(stu.name);
    console.log(stu.showName())
    



    拖拽例子:

    function Drag(className) {
    
        this.dom = document.createElement('div');
        this.dom.className = className;
        document.body.appendChild(this.dom)
    
        this.disX = 0;
        this.disY = 0;
    
        // 初始化
        this.init()
    
    }
    
    Object.assign(Drag.prototype, {
        // 初始化函数
        init() {
            this.dom.onmousedown = function (e) {
                this.down(e)
    
                document.onmousemove = this.move.bind(this)
                document.onmouseup = this.up
            }.bind(this)
        },
    
        down(e) {
            // console.log(e.clientX, e.clientY)
            this.disX = e.clientX - this.dom.offsetLeft;
            this.disY = e.clientY - this.dom.offsetTop;
            // console.log(this.disX, this.disY)
        },
    
        move(e) {
            // console.log(this)
            this.dom.style.left = e.clientX - this.disX + 'px';
            this.dom.style.top = e.clientY - this.disY + 'px';
        },
    
        up(e) {
            // console.log(this)
            document.onmousemove = null;
            document.onmouseup = null;
        }
    })
    
    
    let left = new Drag('left')
    

    ES 6

    class Drag {
        constructor(className) {
            this.dom = document.createElement('div');
            this.dom.className = className;
            document.body.appendChild(this.dom)
    
            this.disX = 0;
            this.disY = 0;
    
            // 初始化
            this.init()
        }
    
        // 初始化函数
        init() {
            this.dom.onmousedown = function (e) {
                this.down(e)
    
                document.onmousemove = this.move.bind(this)
                document.onmouseup = this.up
            }.bind(this)
        }
    
        down(e) {
            // console.log(e.clientX, e.clientY)
            this.disX = e.clientX - this.dom.offsetLeft;
            this.disY = e.clientY - this.dom.offsetTop;
            // console.log(this.disX, this.disY)
        }
    
        move(e) {
            // console.log(this)
            this.dom.style.left = e.clientX - this.disX + 'px';
            this.dom.style.top = e.clientY - this.disY + 'px';
        }
    
        up(e) {
            // console.log(this)
            document.onmousemove = null;
            document.onmouseup = null;
        }
    }
    
    let left = new Drag('left')
    

    通过继承创建有边界的拖拽

    class LimitDrag extends Drag {
        move(e) {
            super.move(e);
    
            this.dom.style.left = Math.max(0, this.dom.offsetLeft) + 'px';
            this.dom.style.left = Math.min(window.innerWidth - this.dom.offsetWidth, this.dom.offsetLeft) + 'px';
    
            this.dom.style.top = Math.max(0, this.dom.offsetTop) + 'px';
            this.dom.style.top = Math.min(window.innerHeight - this.dom.offsetHeight, this.dom.offsetTop) + 'px';
        }
    }
    
    let right = new LimitDrag('right')
    

    相关文章

      网友评论

          本文标题:第三十二节: ES6 Class类

          本文链接:https://www.haomeiwen.com/subject/tgmgmktx.html