ES6 class命令浅识

ES6中的class是一个基于prototype继承的语法糖,它提供了更接近传统语言的写法,引入了class(类)这个概念作为对象的模版。通过class关键字可以定义类,但是通过class做的工作,es5也可以做到,只是通过class,可以使我们的工作更加方便。

在我们JavaScript语言,生成实例对象的传统办法是通过构造函数,如下:

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

但当我们学完ES6class命令后可以把上述代码换成下面这种

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

//等同于,ES5写法

Point。prototype={
  constructor(){},
  toString(){},

}
//注:类的所有方法都定义在类的prototype属性上面。

 新的class写法让对象原型的写法更加清晰、更像面向对象编程的语法。另外class的函数声明没有函数声明提升。

一、类的创建与实例化

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

class Star{
            constructor(uname,age){
                this.uname=uname;//this.uname指向创建的实例
                this.age=age;
          this.btn=document.querySelector('button');
          this.btn.onclick=this.say;
        //
this.btn.onclick=this.say();代表立即调用

}
       say(){
            console.log(this.uname);//undefined.因为this指向btn
        
          } }
var ldh=new Star('刘德华',18); console.log(ldh);

值得注意的几点:

1.  通过class关键字创建类,类名我们还是习惯性定义首字母大写
2.  类里面的constructor函数,可以接受传递过来的参数,同时返回实例对象
3.  constructor 函数只要new生成实例时,就会自动调用这个函数,如果不写也会自动调用
4.  创建类,类名后面不加小括号;生成实例,类后面加小括号,构造函数不需要加function

5.  类没有变量提升,所以必须先定义类,才能通过类实例化对象;

6. 类里面的共有的属性和方法一定要加this使用

二、类中添加共有方法

 

class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  
  get area() {
    return this.calcArea();
  }

  calcArea() {
    return this.height * this.width;
  }
}

const square = new Polygon(20, 20);
const sss = new Polygon(10,250);
console.log(square._proto_ === sss._proto_); //true
console.log(square.area); //400
console.log(sss.area); //2500

值得注意的是:

1.  我们类里面所有的函数不需要写function

2.  多个函数之间不需要添加逗号隔开

3.   实例的属性除非显示定义在其本身(即this对象)上,否则都是定义在原型上的。

 

三、类的继承

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

基本语句格式:

class Father{
             //...
         }
 class Son extends Father{
              
          }

下面用一简单的例子加深了解

//案例一       
class Father{ constructor (){ } say(){ return '我是爸爸';
} } class Son extends Father{ say(){
          console.log('我是儿子');  
            } }
var son=new Son(); son.say();//我是儿子



//案例二 通过super关键字访问和调用对象父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数

   class Father{
    constructor (x,y){
    this.x=x;
    this.y=y
    }
    sum(){
    console.log(this.x+this.y);
    }
    }
   class Son extends Father{
    constructor(x,y){
    super (x,y);//调用了父类中构造函数
    }
    }
    var son=new Son(1,2);
    son.sum();

//案例三  子类继承父类方法,同时还拓展自己的方法

class Father{
    constructor (x,y){
    this.x=x;
    this.y=y
    }
    sum(){
    console.log(this.x+this.y);
    }
    }
   class Son extends Father{
    constructor(x,y){
    super (x,y);//调用了父类中构造函数
    //super 必须在子类this之前调用
    this.x=x;
    this.y=y;
    }
    subtract(){
      console.log(this.x - this.y);
    }
   }
    var son=new Son(5,2);
    son.subtract();
    son.sum();
//son(5,2)先将参数传给子类的构造函数,先弄自身减法,再通过super传给父类的构造函数,实现继承的方法

注: 

1.子类必须在constructor方法中调用super方法。否则新建实例时会报错。

2.子类在构造函数中使用super,必须放到this前面

四、类里面this指向问题

1.在constructor  里面的this 指向的是 创建的实例对象

2.函数方法里面的this指向调用者

验证如下


var that;
var that2;
class Star{
  constructor(uname){
    that=this;
    
  }
  dance(){
that2=this;
    console.log(this);
  }
}
var zxy=new Star('张学友');
console.log(that ===zxy);//true
zxy.dance();
console.log(that2 ===zxy);//true

 

 

posted @ 2019-08-25 06:35  smile小吴  阅读(316)  评论(0编辑  收藏  举报