ES6中的类(Class)

简介: ES6中的类(Class)

类的基本语法


ES6提供了更接近面向对象(注意:javascript本质上是基于对象的语言)语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。 基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。


//定义类
class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
}
//创建对象
let p = new Point(1,2);
console.log(p.toString());

上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5的构造函数Point,对应ES6的Point类的构造方法。


Point类除了构造方法,还定义了一个toString方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。


注意:生成类的实例对象的写法,要使用new命令。如果忘记加上new,像ES5函数那样调用Class,将会报错。


// 报错
let point = Point(2,3);
// 正确
let point = new Point(2,3);


constructor方法


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


constructor() {}

注意:constructor方法默认返回实例对象(即this)


扩展:constructor方法默认返回实例对象(即this),但也可以指定返回另外一个对象。


样例代码:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <script>
      class Point {
          constructor() {
              return new Date();
              //return Object.create(null);
          }
      }
      let p = new Point();   //返回为Date对象
      console.log(p);
    </script>
  </body>
</html>

效果截图:

22.png

Constructor与普通构造函数的区别: 类的构造函数,不使用new是没法调用的,会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。


class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
}
let p = Point(); //TypeError: Class constructor Point cannot be invoked without 'new'


this与class(原型)


class:类,是对象的模板。(或者叫:原型) this:当前对象。 以上定义,与java中的概念是相同的。 但是,由于javascript语言自身的特点,关于class与this,还需要做进一步说明。


注意:在javascript中,在定义类完毕之后,还可以再添加属性和方法。


属性与方法添加到this上


class Point {
    constructor() { }
}
let p = new Point();
p.username = 'zhangsan';
console.log(p.username);    //zhangsan

上面代码中,Point类定义之后,给对象 p 又添加了一个username属性。这是完全可以的。 但是要注意:此种方式,仅仅是给对象p添加一个属性,而不是给类添加一个属性。 或者说: 此种方式,仅仅是给对象p的this添加一个属性,而不是给类添加一个属性。


class Point {
    constructor() { }
}
let p1 = new Point();
p1.username = 'zhangsan';
console.log(p1.username);   //zhangsan
let p2 = new Point();
console.log(p2.username);   //undefined

上面例子中,只给对象p1添加了username属性,但没有给类添加属性。 所以,p2对象中并没有username属性。


属性与方法添加到类上


class Point {
    constructor() { }
}
Point.prototype.username = 'zhangsan';
let p1 = new Point();
console.log(p1.username);   //zhangsan
let p2 = new Point();
console.log(p2.username);   //zhangsan

上面代码中,使用 Point.prototype方式,给类添加属性。 这样,类的所有对象(p1、p2)就都有username属性了。


在javascript中,每一个类都有一个prototype,它就是类的原型,类的所有实例共享一个原型。如果想访问这个原型,可以使用proto指针。


样例代码:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <script>
      class Point {
       constructor() { }
      }
      let p = new Point();
      console.log(p.__proto__);      //注意proto指针的写法
      /**
       * 输出结果:
       * {constructor: ƒ}
       *  constructor: class Point  //这里证明:proto指针指向类的原型
       *  __proto__: Object
       */
      let p1 = new Point();
      let p2 = new Point(); 
      //这里证明:类的所有实例共享一个原型 
      console.log(p1.__proto__===p2.__proto__);  //true
    </script>
  </body>
</html>

效果截图:

23.png


类的静态成员


样例代码:


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <script>
      class Point {
          constructor() { }
      }
      Point.username = '牛哄哄的柯南';
      let p = new Point();
      console.log(p.username);        //undefined
      console.log(Point.username);   //牛哄哄的柯南
    </script>
  </body>
</html>

效果截图:

24.png



上面代码中,直接使用 Point.username 方式给类添加一个属性,此种方式只是添加了一个静态属性,访问时,只能通过类名才能访问。


相关文章
|
8月前
|
JavaScript
对TS里接口、extends和类的理解
对TS里接口、extends和类的理解
47 1
|
5月前
ES6中的class类
ES6中的class类
28 0
|
10月前
|
存储 JavaScript
【TS】class类和接口
【TS】class类和接口
65 0
|
10月前
ES6 class使用方法
ES6 class使用方法
43 0
|
10月前
|
JavaScript
【ES6】类
【ES6】类
42 0
|
JavaScript Java C++
ES6-Class如何优雅的进行“糖化”
这是一篇番外篇,其实他的主线是由一篇ES6-Class科普文章引发的“惨案”。虽然是番外篇,但是有些剧情还是不容错过的。 现在我们来进入番外篇的主线:ES6的Class是ES5构造函数的语法糖。
|
JavaScript 前端开发 Java
ES6_Extends如何对ES5的继承进行“糖化”
我用我拙劣的代码来将这层糖的成分细细分析一下。 下面一些方法,都是基于class被脱糖之后的分析。关于class是如何被脱糖的过程===&gt;请先查看ES6-Class如何优雅的进行Prototype“糖化” 内容很精彩,但是不要忘记回来看这个。这个剧情也挺赤鸡的。
|
前端开发
前端小案例1-es6中 class的重写
前端小案例1-es6中 class的重写
45 0
前端小案例1-es6中 class的重写
|
前端开发
前端小案例1-es6中 class的重写2
前端小案例1-es6中 class的重写2
47 0
前端小案例1-es6中 class的重写2