ES6:Class基本用法

  • Post author:
  • Post category:其他




关于Class

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,

作为对象的模板。通过class关键字,可以定义类。

基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,

新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。


1.我们先用构造函数来构造一个对象:

    function Point (x,y) {
        this.x = x;
        this.y = y;        
    }              
    Point.prototype.show = function () {
        console.log('hello world');
    }                                      
    var demo = new Point(1,2);
    demo.show();


2.然后我们用Class类来改写一下:

    class Point{
      constructor(x,y){
        this.x = x;
        this.y = y;
      }
      show(){
        console.log('hello world');
      }
    }
    var demo = new Point(1,2);
    demo.show();

代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而

this关键字

则代表

实例对象



注意,定义“类”的方法的时候,前面

不需要

加上

function

这个保留字,直接把函数定义放进去了就可以了。

另外,方法之间

不需要逗号分隔

,加了会报错。


3.Class数据类型:

      class Point {}
      console.log(typeof Point);
      //function
      console.log(Point === Point.prototype.constructor);
      //true

我们发现类的数据类型就是函数,类本身就指向构造函数。


4.constructor方法


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

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

      class Foo {
        constructor() {
          return Object.create(null); 
        }
      }
      console.log(new Foo() instanceof Foo);
      //false

默认返回实例对象 但是

更改后

就是

新的对象。



5.prototype属性

构造函数的prototype属性,在ES6的“类”上面继续存在。

事实上,类的所有方法都定义在类的prototype属性上面。

      class Point {
        constructor() {
          this.x = 10;
          alert(0);
        }
        toString() {
          alert("1");
        }
        toValue() {
          alert("2");
        }
      }
      console.log(Point.prototype);
      //{constructor: ƒ, toString: ƒ, toValue: ƒ}

另外要注意的是类内部所有定义的方法都是不可枚举的

      class Point {
        constructor (x,y) {
        }
        toString() {
            console.log(1);
        }        
    }    
    
    function Point1 () {
        this.toString = function () {
            console.log(1);
        }
    }
    Point1.prototype.toValue = function () {
        console.log(2);
    }                
    var demo = new Point();
    var demo1 = new Point1();
       
    for (var prop in demo) {
        console.log(prop);
        //不可枚举
    }              
    for (var prop in demo1) {
        console.log(prop);
        //toString
		//toValue
    }


6.类的实例共享一个原型对象:

      class Point {}

      var demo1 = new Point();
      Point.prototype.say = function() {
        console.log("hello");
      };

      var demo2 = new Point();
      demo2.__proto__.printName = function() {
        console.log("world");
      };

      var demo3 = new Point();

      demo1.printName();
      		//hello
      demo2.printName();
     	 	//hello
      demo3.printName();
      		//hello

      demo1.say();
          //world
      demo2.say();
          //world
      demo3.say();
          //world



实例的__proto__

指向构造函数



prototype



7.name属性


name 属性 由于本质上,ES6的Class只是ES5的构造函数的一层包装,所以函数的许多特性都被Class继承,包括name属性。

代码使用表达式定义了一个类。需要注意的是,

这个类的名字是

MyClass

而不是

Me



Me

只在Class的

内部代码

可用,指代

当前类



如果Class

内部没用到

的话,

可以省略Me

,也就是可以写成下面的形式:

      const MyClass = class Me {
        getClassName() {
          return Me.name;
        }
      };
      let demo = new MyClass();
    console.log(demo.getClassName());
    //Me

同时Class

不存在变量提升




8.继承


Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。

      class Father {
        constructor() {
          this.name = 'He';
        }
        static show() {
        console.log('hello dad');
        }
        eat(){
          console.log('eat');
        }
      }
      class Child extends Father {
        constructor() {
          super();
          this.hobby = "sing";
        }
        static ChildShow(){
          super.show();
        }
        childEat(){
          super.eat();
        }
      }
      var baby = new Child();
      Child.ChildShow();
       //hello dad
      baby.childEat();
       //eat
      var dad = new Father();
      Father.show();
       //hello dad

静态方法继承的时候也需要借助我们的super方法,

静态的super指向的是类



非静态方法指向的是原型

。并且静态方法

只能继承

静态方法而不能去继承其他方法。这是因为

静态方法直接在类上调用

,而不是在类的实例上调用。普通方法是

绑定在类的原型链

上,两者继承的话会找不到对应方法而报错。



版权声明:本文为qq_44042205原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。