2.ES6引进的新特性——类Class

     

为什么?

       ES6中引入了类,类在java/c++等面向对象的编程语言常见,JS引入类是为了在日后使用js开发大型的应用程序,类本质是语法糖(语法上更加人性化)

 

以前写一个类

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

// 静态方法
User.getClassName = function () {
   return 'User'
};

// 为类添加公用方法,在原型对象上加
User.prototype.changeName = function (name) {
   this.name = name
}
User.prototype.changeAge = function (age) {
   this.age = age
}

// 为类添加取值函数与存值函数(都要写到原型对象上去)
Object.defineProperty(User.prtotype, 'info', {
   get(){
      return 'name:' + this.name + ' | age:' + this.age;
   }
});


// 新建一个子类
function Manager(name, age, password){
   User.call(this,name,age);  // 也可以User.apply(this, arguments),意思是调用父类的构造函数,从而达到继承父类属性的效果,注意,只能继承父类实例属性,而继承不了父类的方法
   this.password = password;
}
// 继承静态方法
Manager._proto_ = User;
// 继承prototype方法(继承父类方法)
Manager.prototype = User.prototype; // 也可以Manager.prototype = new User()
// 添加新方法
Manager.prototype.changePassword = function(pwd){
   this.password = password;
};

// 验证是否能继承
var manager = new Manager('kkk', 22, '123');
manager.changeName('lighter');
console.log(manager.name)   //  输出 lighter
console.log(manager.info);  //  输出 name:lighter | age:22

  

可以看出,以前ES5写一个类,虽然可以实现类的继承,但是很不优雅--!

 

ES6优雅写类

我们来注释上面的代码,一段一段地看它们又什么区别

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

class User{
   constructor(name, age){
       this.name = name;
       this.age = age;
   }



    //// 静态方法
    //User.getClassName = function () {
    //   return 'User'
    //};
    
    // 静态方法
    User.getClassName = function () {
        return 'User';
    }


    
    //// 为类添加公用方法,在原型对象上加
    //User.prototype.changeName = function (name) {
    //   this.name = name
    //}
    //User.prototype.changeAge = function (age) {
    //   this.age = age
    //}

    // 为类添加公用方法,在原型对象上加
    changeName(name) {
        this.name = name
    }
    changeAge(age) {
        this.age= age
    }



    //// 为类添加取值函数与存值函数(都要写到原型对象上去)
    //Object.defineProperty(User.prtotype, 'info', {
    //   get(){
    //      return 'name:' + this.name + ' | age:' + this.age;
    //   }
    //});

    // 为类添加取值函数与存值函数(都要写到原型对象上去)
    get info() {
        return 'name:' + this.name + ' | age:' + this.age;
    }

}


// 新建一个子类
//function Manager(name, age, password){
//   User.call(this,name,age);
//   this.password = password;
//}
//// 继承静态方法,原型链就是实力对象_proto_属性
//Manager._proto_ = User;
//// 继承prototype方法
//Manager.prototype = User.prototype;


class Manager extends User{
    constructor(name, age, password){
        super(name,age);
        this.password = password;
    }

    //// 添加新方法
    //Manager.prototype.changePassword = function(pwd){
    //   this.password = password;
    //};    

    changePassword(password){
        this.password = password
    }
}



// 然后下面的用法都是一样的。


// 验证是否能继承
var manager = new Manager('kkk', 22, '123');
manager.changeName('lighter');
console.log(manager.name)   //  输出 lighter
console.log(manager.info);  //  输出 name:lighter | age:22

 

 语法糖

注意,例如上面写的class 等概念,就是语法糖,它方便了我们写代码,使得代码更加地简洁,无论是class User ,还是class Manager,它们本质都是function

console.log(typeof User, typeof Manager);

//输出  function   function

 

简写继承

class I extends User {  
}
var me = new I('psg', 23);
console.log(me);

//不报错,输出   I {name: 'psg', age: 23}

 

上面继承没加构造函数constructor,但是内部默认会加,上面的代码会变成下面这个样子:

class I extends User{
    constructor(...arg){
        super(...arg);
    }  
}

 

 

总结ES6继承的重点

1.继承时候,如果手写构造函数,那么在constructor块里面,第一行写super(....),因为它要先创建父类的对象,然后所有的方法(上面的changePassword)、属性(上面的password)都会加到父类创建的对象上。

 

2.使用super可以改变父类的方法,例如上面的Manager类,它继承User父类,现在我想改变从父类中继承的info方法,我加一点东西,使我Manager有别于父类,但是我还是调用同样父类方法的名字,这时我可以这样写:

class Manager extends User{
    constructor(name, age, password){
        super(name,age);
        this.password = password;
    }

    //// 添加新方法
    //Manager.prototype.changePassword = function(pwd){
    //   this.password = password;
    //};    

    changePassword(password){
        this.password = password
    }
    //使用super改写父类的方法
    get info() {
        var info = super.info;  // 注意!!这里的info没有()
        console.log(info);
        return info + '--new'
    }
}
var manager = new Manager('kkk', 22, '123');
console.log(manager.info);  
// 输出 name:lighter | age:22
//  输出 name:lighter | age:22---new

  

 

创建立即执行的类

'use strict'
let user = new class User{
    constructor(name){
        this.name = name;  
    }
}('psg');

console.log(user);

//输出 User {name: 'psg'}

  

不被提升

'use strict'

var user = new User();

class User{
    constructor(name){
        this.name = name;  
    }
}

console.log(user);

//ReferenceError: User is not defined

  

 

 

 

 

 

 

 

 

 

-----完-----

 

posted @ 2017-10-25 22:54  彭胜光  阅读(207)  评论(0编辑  收藏  举报