es6-class学习记录

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

一、基本语法

//es6之前类实现
//Person.js
function Person(name,msg){
    this.name = name;
    this.msg= msg;
}
 
Person.prototype.toString = function (){
    return (`${this.name} ${this.msg}`);
}

export {Person};
//index.js
import {Person} from './Person';
let p=new Person('哥哥','俺也要')
console.log(p.toString()) // 哥哥 俺也要
//es6后class用法
//Person.js
class Person{
    // 构造
    constructor(name,msg){
        this.name = name;
        this.msg = msg;
    }
 
    toString(){
        return (`${this.name} ${this.msg}`);
    }
}
export {Person};
//index.js
import {Person} from './Person';
let p=new Person('哥哥','俺也要')
console.log(p.toString()) // 哥哥 俺也要
/*在es6之前我们使用构造函数的prototype属性来添加方法,prototype在ES6的“类”上面继续存在。
事实上,类的所有方法都定义在类的prototype属性上面,我们在定义类的时候也可以通过这个方式添加方法。*/
//index.js
console.log(person.constructor === Person.prototype.constructor);//true

//index.js
Person.prototype = {
    getName(){
        return '哥哥';
    },
    getMsg(){
        return '俺也要';
    }
};
/*我们都知道Object.assign方法可以给对象Person动态的增加方法,而Person.prototype = {}则是覆盖对象的
方法,或者在初始化的时候添加方法。*/
//index.js
Object.assign(Person.prototype,{
    getAge(){
        console.log('12');
    },
    getClass(){
        console.log('3');
    }
});

二、原型链上

/*Object.keys(obj),返回一个数组,数组里是该obj可被枚举的所有属性
Object.getOwnPropertyNames(obj),返回一个数组,数组里是该obj上所有的实例属性*/
//在类内部定义的方法,ES6中它是不可枚举的,这一点与ES5的行为不一致,ES5是可以枚举的。

//ES5
console.log(Object.keys(Person.prototype));//["toString", "getAge", "getClass"]
console.log(Object.getOwnPropertyNames(Person.prototype));//["constructor", "toString", "getAge", "getClass"]
 
//ES6
console.log(Object.keys(Person.prototype));//["getAge", "getAge"]
console.log(Object.getOwnPropertyNames(Person.prototype));//["constructor", "toString", "getAge", "getClass"]
//_proto_

console.log(person.hasOwnProperty('name'));//true
console.log(person.hasOwnProperty('msg'));//true
console.log(person.hasOwnProperty('toString'));//false
console.log(person.__proto__.hasOwnProperty('toString'));//true
//从上面可以看出name,msg是定义在this对象上,toString定义在类上的
/*我们知道类的所有实例共享一个原型对象,所有Person的实例它们的原型都是Person.prototype,
所以每个实例的__proto__属性是相等的。也就是说,可以通过实例的__proto__属性为Class添加方法。*/

let person1 = new Person('老李','你真是个人才');
let person2 = new Person('老张','我也觉得');
person1.__proto__.getText = function (){
    return "这是新增的一条信息";
};
console.log(person1.getText ());//这是新增的一条信息
console.log(person2.getText ());//这是新增的一条信息
/*class不存在变量提升,需要先定义再使用,因为ES6不会把类的声明提升到代码头部,但是ES5就不一样,
ES5存在变量提升,可以先使用,然后再定义。*/
//正确
new A();
function A(){
 
}//ES5可以先使用再定义,存在变量提升
//错误
new B();
class B{
 
}//B is not a constructor
//ES6不能先使用再定义,不存在变量提升
/*类相当于实例的原型,所有在类中定义的方法,都会被实例继承。
如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。*/
//在静态方法包含this关键字,这个this指的是类,而不是实例,虽然类的静态方法不可被实例所继承,但是却可以被子类继承。
class Say {
  static fa() {
    this.fa_s();
  }
  static fa_s() {
    console.log('hello');
  }
  fa_s() {
    console.log('world');
  }
}

class Tell extends Say{
    fa_t() {
        console.log('world');
    }
}

Tell.fa()//hello
Tell.fa_s()//hello
Tell.fa_t()//Uncaught TypeError: Tell.fa_t is not a function
let t=new Tell
t.fa()//Uncaught TypeError: t.fa is not a function
t.fa_s()//world
t.fa_t()//world
Say.fa()//hello
Say.fa_s()//hello
let s=new Say
s.fa()//s.fa is not a function
s.fa_s() // world

//子类继承父类静态方法
class Say {
  static fa() {
    this.fa_s();
  }
  static fa_s() {
    console.log('hello');
  }
}

class Tell extends Say{
    fa_t() {
        console.log('world');
    }
}
Tell.fa()//hello
console.log(Object.getOwnPropertyNames(Say.prototype))// ["constructor","fa_s"]
console.log(Object.getOwnPropertyNames(Tell.prototype))//["constructor","fa_t"]

三、继承

super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同.

第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。

第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
//子类的_prop_属性,表示构造函数的继承,总是指向父类。
//子类prototype属性的_prop_属性,表示方法的继承,总是指向父类的prototype属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值