资讯专栏INFORMATION COLUMN

ES6 Class类

trigkit4 / 683人阅读

摘要:声明和定义声明一个构造函数声明一个类以上两者相比之下,很可以看出,类函数比构造函数,代码量更少,并且结构层次更加简洁明了。类主要内容是构造函数静态方法继承。构造函数一个类里,必有一个函数,默认。

ES6 Class类
ES6中class是基于原型的继承的语法糖,提供更加清晰的语法来创建对象和原型。
声明和定义

es5 声明一个构造函数:

function Student(name, age) {
    this.name = name;
    this.age = age;
}

Student.prototype.getInfo = function() {
    return "{name:" + this.name + ",age:" + this.age + "}";
}

Student.prototype.setInfo = function(name, age) {
    this.name = name;
    this.age = age;
}

var p = new Student("nico", 1);
p.getInfo(); //{name:nico,age:1}
p.setInfo("siip", 10);
p.getInfo(); //{name:siip,10}

es6 声明一个类:

class Student {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    getInfo() {
        return `{name:${this.name},age:${this.age}}`;
    }
    setInfo(name, age) {
        this.name = name;
        this.age = age;
    }
}
let p = new Student("nico", 1);
p.setInfo("siip", 10);
p.getInfo();//{name:siip,10}

以上两者相比之下,很可以看出,es6类函数比es5构造函数,代码量更少,并且结构层次更加简洁明了。

有些地方需要注意的是:

es5存在变量提升(var xxx,function xxx(){})

es6不存在变量提升(const,let,class)

Class 方法

constructor

constructor是默认的方法,就算在声明类函数时没有写constructor方法,在实例化时会自动添加上一个空的constructor

class Student {
    constructor() {
        this.desc = "test";
    }
}

通过babel转码:

   function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
            throw new TypeError("Cannot call a class as a function");
        }
    }

    var Student = function Student() {
        _classCallCheck(this, Student);//类不能直接被调用,只能通过new实例化

        this.desc = "test";
    };

constructor方法指向自身,在一个类中只能有一个名为 “constructor” 的特殊方法。

Student === Student.prototype.constructor;//true

static

简述:顾名思义这是一个静态方法,就是不需要实例化类就可以调用的方法, 实例化对象不能继承静态方法。

class Student {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    static ageFilter(...args) {
        let stuAge = args;
        let arr = [];

        for (let i = 0; i < stuAge.length; i++) {
            if (stuAge[i].age > 12) {
                arr.push(stuAge[i])
            }
        }
        return arr;
    }
    getInfo() {
        return `{name:${this.name},age:${this.age}}`;
    }
    setInfo(name, age) {
        this.name = name;
        this.age = age;
    }
}
Student.ageFilter({
    name: "a",
    age: 1
}, {
    name: "b",
    age: 14
});//{name: "a", age: 14}

静态函数的this指向类函数自身,当this没有指明被谁调用时,this为undefined

我们将上面代码用babel编译,从结果上看:

    var _createClass = function() {
        function defineProperties(target, props) {
            for (var i = 0; i < props.length; i++) {
                var descriptor = props[i];
                descriptor.enumerable = descriptor.enumerable || false;
                descriptor.configurable = true;
                if ("value" in descriptor) descriptor.writable = true;
                Object.defineProperty(target, descriptor.key, descriptor);
            }
        }
        return function(Constructor, protoProps, staticProps) {
            if (protoProps) defineProperties(Constructor.prototype, protoProps);
            if (staticProps) defineProperties(Constructor, staticProps);
            return Constructor;
        };
    }();

从代码可以看出,静态方法与类函数方法的区别是:当用Object.defineProperty去定义对象属性时传入的对象不同,一个传入的是构造函数的原型,另一个是传入构造函数。

es6当前还不支持静态属性

extends

关键字在类声明或类表达式中用于创建一个类作为另一个类的一个子类
class Student {
    constructor(name = null, age = null) {
        this.name = name;
        this.age = age;
    }
    getInfo() {
        return `{name:${this.name},age:${this.age}}`;
    }
    setInfo(name, age) {
        this.name = name;
        this.age = age;
    }
}

class Citizen extends Student {
    constructor(name, age) {
        super(name, age);
        this.name = 123;
    }
}
let stu = new Citizen("siip", "25");
stu.getInfo(); //{name:siip,age:25}

可以看到子类可以调用父类上的方法和属性,当使用extends继承父类时,子类constructor和super和被默认添加上,并且在构造函数内,只有调用了super函数后才能使用this,否则会抛出ReferenceError错误

     constructor() {
        this.name = "xxx"
         super()
      }//ReferenceError

super

super可作为一个函数使用

super可作为一个对象使用

下面一个子类继承父类的Math的方法:

function MathFns() {
    this.status = "Father"
}
MathFns.prototype = Math;

class Max extends MathFns {
    constructor() {
        super();
    }
    static base() {
        return super.max();
    }
}
let m = new MathFns();
m; //{status: "Father"}
m.max(1, 2);//2

我们可以通过babel编译,尝试去理解es6的继承,

function _inherits(subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        }
    });

    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;

}

这个封装继承函数,主要实现的功能是,子类原型指向父类,原型构造器指向自身,然后再通过隐式原型链指向父类函数,这样子类被实例化后的对像就能使用父类原型链上的方法以及通过隐式原型链访问到父类的属性。

总结

总的来看,es6的class类实际上是基于原型链和继承做的一层封装,它的结构层次相对于es5原型链写法更加清晰明了,代码量更少。class类主要内容是构造函数、静态方法、继承。

构造函数

一个类里,必有一个constructor函数,默认。

类不存在变量提升

一个类里只能有一个constructor函数

constructor函数指向类自身

静态方法

静态函数的this指向类函数自身,当this没有指明被谁调用时,this为undefined

在同一个类中的一个静态方法调用另一个静态方法

类实例化对象不能调用类静态方法

继承

子类继承父类的属性和方法

在子类继承父类,子类的构造函数中要先调用super函数,才能使用this

super可以作为函数或对象调用,但指向都是子类

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107354.html

相关文章

  • ES6】更易于继承的语法

    摘要:的类使用熟悉的关键字指定类继承的函数,并且可以通过方法访问父类的构造函数。例如继承一个的类继承了,术语上称为基类,为派生类。例如注意到上例中,不仅是派生类的实例,也是派生类的实例,内建对象继承的实用之处是改变返回对象的类型。 和其它面向对象编程语言一样,ES6 正式定义了 class 类以及 extend 继承语法糖,并且支持静态、派生、抽象、迭代、单例等,而且根据 ES6 的新特性衍...

    Lionad-Morotar 评论0 收藏0
  • es6 -

    摘要:创建自定义类型看下面一段代码上面代码使用创建了一个自定义类型,是这个类的构造器,是类的公共方法。注意事项在使用类继承的实现中,需要注意的点是如果子类没有重写方法,默认会调用父类的构造器方法。 es6 类-class 与大多正规的面向对象编程语言不同(比如java),js在创建之初就不支持类。js的面向对象编程实现方式是通过构造函数和原型来实现的。 我之前以为es6引入类的概念将会带给这...

    notebin 评论0 收藏0
  • ES6学习总结(三)

    摘要:不同于其他面向对象语言,以前的中中没有类的概念,主要是通过原型的方式来实现继承,中引入了原型链,并且将原型链用来实现继承,其核心是利用原型使得一个对象继承另一个对象的方法和属性,中原型继承的关键是将一个实例的原型对象指向另一个实例,因此前一 不同于其他面向对象语言,ES6以前的JavaScript中中没有class类的概念,主要是通过原型的方式来实现继承,JavaScript中引入了原...

    baoxl 评论0 收藏0
  • ES6Class创建对象与继承实现

    摘要:使用类创建实例对象也是直接对类使用命令,跟中构造函数的用法一致。中没有构造函数,作为构造函数的语法糖,同时有属性和属性,因此同时存在两条继承链。子类的属性,表示构造函数的继承,总是指向父类。 1 Class in ES6 ES6提出了类(Class)的概念,让对象的原型的写法更像面向对象语言写法。 ES6中通过class定义对象,默认具有constructor方法和自定义方法,但是包含...

    zhou_you 评论0 收藏0
  • ES6Class创建对象与继承实现

    摘要:使用类创建实例对象也是直接对类使用命令,跟中构造函数的用法一致。中没有构造函数,作为构造函数的语法糖,同时有属性和属性,因此同时存在两条继承链。子类的属性,表示构造函数的继承,总是指向父类。 1 Class in ES6 ES6提出了类(Class)的概念,让对象的原型的写法更像面向对象语言写法。 ES6中通过class定义对象,默认具有constructor方法和自定义方法,但是包含...

    wind5o 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<