这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
class 是 es6 引入的最重要特性之一。在没有 class 之前,我们只能通过原型链来模拟类。这篇文章我们将详细的介绍关于 ES6 中 CLASS 的使用,有需要的朋友们可以参考借鉴,下面来一起看看吧。
前言
对于 javascript 来说,类是一种可选(而不是必须)的设计模式,而且在 JavaScript 这样的 [[Prototype]] 语言中实现类是很蹩脚的。
这种蹩脚的感觉不只是来源于语法,虽然语法是很重要的原因。js 里面有许多语法的缺点:繁琐杂乱的. prototype 引用、试图调用原型链上层同名函数时的显式伪多态以及不可靠、不美观而且容易被误解成 "构造函数" 的. constructor。
除此之外,类设计其实还存在更进一步的问题。传统面向类的语言中父类和子类、子类和实例之间其实是复制操作,但是在 [[Prototype]] 中并没有复制。
对象关联代码和行为委托使用了 [[Prototype]] 而不是将它藏起来,对比其简洁性可以看出,类并不适用于 JavaScript。
ES6 中 CLASS 的使用
javascript 传统做法是当生成一个对象实例,需要定义构造函数,然后通过 new 的方式完成。
- function StdInfo(){
- this.name = "job";
- this.age = 30;
- }
- StdInfo.prototype.getNames = function (){
- console.log("name:"+this.name);
- }
- //得到一个学员信息对象
- var p = new StdInfo()
javacript 中只有对象,没有类。它是是基于原型的语言,原型对象是新对象的模板,它将自身的属性共享给新对象。这样的写法和传统面向对象语言差异很大,很容易让新手感到困惑。
定义类
到了 ES6 添加了类,作为对象的模板。通过 class 来定义一个类:
- //定义类
- class StdInfo {
- constructor(){
- this.name = "job";
- this.age = 30;
- }
- //定义在类中的方法不需要添加function
- getNames(){
- console.log("name:"+this.name);
- }
- }
- //使用new的方式得到一个实例对象
- var p = new StdInfo();
上面的写法更加清晰、更像面向对象编程的语法,看起来也更容易理解。
定义的类只是语法糖,目的是让我们用更简洁明了的语法创建对象及处理相关的继承。
- //定义类
- class StdInfo {
- //...
- }
- console.log(typeof StdInfo); //function
- console.log(StdInfo === StdInfo.prototype.constructor); //true
从上面的测试中可以看出来,类的类型就是一个函数,是一个 "特殊函数",指向的是构造函数。
函数的定义方式有函数声明和函数表达式两种,类的定义方式也有两种,分别是:类声明和类表达式。
类声明
类声明是定义类的一种方式,使用关键字 class,后面跟上类名,然后就是一对大括号。把这一类需要定义的方法放在大括号中。
- //定义类,可以省略constructor
- class StdInfo {
- getNames(){
- console.log("name:"+this.name);
- }
- }
- // -------------------------------------
- //定义类,加上constructor
- class StdInfo {
- //使用new定义实例对象时,自动调用这个函数,传入参数
- constructor(name,age){
- this.name = name;
- this.age = age;
- }
- getNames(){
- console.log("name:"+this.name);
- }
- }
- //定义实例对象时,传入参数
- var p = new StdInfo("job",30)
constructor 是一个默认方法,使用 new 来定义实例对象时,自动执行 constructor 函数,传入所需要的参数, 执行完 constructor 后自动返回实例对象。
一个类中只能有一个 constructor 函数,定义多个会报错。
constructor 中的 this 指向新创建的实例对象,利用 this 往新创建的实例对象扩展属性。
在定义实例对象时,不需要在初始化阶段做一些事,可以不用显示的写 constructor 函数。如果没有显式定义,一个空的 constructor 方法会被默认添加,constructor(){}
类表达式
类表达式是定义类的另一种形式,类似于函数表达式,把一个函数作为值赋给变量。可以把定义的类赋值给一个变量,这时候变量就为类名。class 关键字之后的类名可有可无,如果存在,则只能在类内部使用。
定义类 class 后面有类名:
- const People = class StdInfo {
- constructor() {
- console.log(StdInfo); //可以打印出值,是一个函数
- }
- }
- new People();
- new StdInfo(); //报错,StdInfo is not defined;
定义类 class 后面没有类名:
- const People = class {
- constructor(){
- }
- }
- new People();
立即执行的类:
- const p = new class {
- constructor(name,age){
- console.log(name,age);
- }
- }("job",30)
立即执行的类,在类前要加上 new。p 为类的实例对象。
不存在变量提升
定义类不存在变量提升,只能先定义类后使用,跟函数声明有区别的。
- //-----函数声明-------
- //定义前可以先使用,因为函数声明提升的缘故,调用合法。
- func();
- function func(){}
- //-----定义类---------------
- new StdInfo(); //报错,StdInfo is not defined
- class StdInfo{}
EXTENDS 继承
使用 extends 关键字实现类之间的继承。这比在 ES5 中使用继承要方便很多。
- //定义类父类
- class Parent {
- constructor(name, age) {
- this.name = name;
- this.age = age;
- }
- speakSometing() {
- console.log("I can speek chinese");
- }
- }
- //定义子类,继承父类
- class Child extends Parent {
- coding() {
- console.log("coding javascript");
- }
- }
- var c = new Child();
- //可以调用父类的方法
- c.speakSometing(); // I can speek chinese
使用继承的方式,子类就拥有了父类的方法。
如果子类中有 constructor 构造函数,则必须使用调用 super。
- //定义类父类
- class Parent {
- constructor(name, age) {
- this.name = name;
- this.age = age;
- }
- speakSometing() {
- console.log("I can speek chinese");
- }
- }
- //定义子类,继承父类
- class Child extends Parent {
- constructor(name, age) {
- //不调super(),则会报错 this is not defined
- //必须调用super
- super(name, age);
- }
- coding() {
- console.log("coding javascript");
- }
- }
- var c = new Child("job", 30);
- //可以调用父类的方法
- c.speakSometing(); // I can speek chinese
子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错 (this is not defined)。这是因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工。如果不调用 super 方法,子类就得不到 this 对象。
总结
好了,以上就是对 ES6 中类的简单总结学习,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对 phperz 的支持。
来源: http://www.phperz.com/article/17/0511/330312.html