浅析JS中的class

5 篇文章 0 订阅

在 ES6 规范中,引入了 class 的概念。使得 JS 开发者终于告别了,直接使用原型对象模仿面向对象中的类和类继承时代。

通过类Class来创建对象,使得开发者不必写重复的代码,以达到代码复用的目的。它基于的逻辑是,两个或多个对象的结构功能类似,可以抽象出一个模板,依照模板复制出多个相似的对象。就像自行车制造商一遍一遍地复用相同的蓝图来制造大量的自行车。

但是JS 中并没有一个真正的 class 原始类型,它的原理依旧是原型继承。 class 仅仅只是对原型对象运用语法糖。

class类概念与语法

ES5之前不存在类的概念,创建对象使用的构造函数,通过new操作符来创建;

为使JS更像面向对象,ES6版本引入class概念,其基本语法:

class Cat{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    Say(){
        return '我的名字是' + this.name;
    }
}
var cat1 = new Cat('有鱼',2);
console.log(cat1.Say());//我的名字是有鱼

原型链图示
在这里插入图片描述

代码解析:

① constructor是一个构造函数方法,创建对象时自动调用该方法

② constructor是默认存在的,可以省略,程序亦可以调用

③ this指的是实例化对象,在本例中,this为cat1

④ 类中声明的方法不能加function关键字

⑤ 方法之间不要用逗号分隔,否则会报错

⑥ 实例对象下面有一个[[prototype]],其实没有标准的方式可以访问它,但是主流浏览器上在每个对象上(null除外)都支持一个属性,那就是__proto__,这个属性会指向该对象的原型

class类与原型的关系

class类本质上就是一个函数,自身指向的就是构造函数,看代码:

console.log(typeof Cat);// function
console.log(Cat.prototype.constructor === Cat);//true

class类是构造函数的另一种写法,仍然存在prototype方法

console.log(Cat.prototype);//object

可以通过原型prototype修改类方法和新增方法

Cat.prototype.Say = function(){
    return return '我的名字是' + this.name+',我是原型prototype声明同样的Say方法,把原有Say方法覆盖了';
}
cat2 = new Cat('年年',5);
console.log(cat2.Say());//我的名字是年年,我是原型prototype声明同样的Say方法,把原有Say方法覆盖了
Cat.prototype.Go = function(){
    return return '我的年龄是' + this.age;
}
console.log(cat2.Go());//我的年龄是5

还可以通过Object.assign方法来为对象动态增加方法

Object.assign(Cat.prototype,{
    Eat:function(){
        return this.name;
    },
    Run:function(){
        return this.age;
    }
})
cat3 =new Cat('卡卡',4);
console.log(cat3.Eat());//卡卡
console.log(cat3.Run());//4

也可以使用实例对象的__proto__属性新增类的方法

cat3 =new Cat('卡卡',4);
cat4 =new Cat('楼楼',10);
cat3.__proto__.Play = function(){
    return this.name;
}
console.log(cat3.Play());// 卡卡
console.log(cat4.Play());// 楼楼
实例属性和原型属性

实例属性:constructor里面的属性为实例属性,即定义在this对象上

原型属性:除去实例属性都称为原型属性,即定义在class类上

hasOwnProperty方法:可以通过hasOwnProperty()方法进行判断属性是否是实例属性

in操作符:能够访问到属性时返回true,无论是实例属性还是原型属性

class Person(){
    constructor(per1,per2){
        this.per1 = per1;
        this.per2 = per2;
    }
    Say(){
        return per1+per2;
    }
}
var box=new Person('年年','有鱼');
console.log(Person.hasOwnProperty("per1"));//true
console.log(Person.hasOwnProperty("per2"));//true
console.log(Person.hasOwnProperty("Say"));//false
console.log("per1" in Person);//true
console.log("per2" in Person);//true
console.log("Say" in Person);//true
console.log("Go" in Person);//false
class类的继承

通过extends关键字实现类的继承

class Person{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    getName(){
        return this.name;
    }
    getAge(){
        return this.age; 
    }
}
class Student extends Person{
    getName(){
        return '我覆盖了父级的方法,'+ this.name;
    }
    getScore(){
        return '我是子级新增的方法,'+this.name;
    }
}
var stu1 = new Student('有鱼',2);
console.log(sut1.getName());// 我覆盖了父级的方法,有鱼
console.log(sut1.getAge());//2
console.log(sut1.getScore());// 我是子级新增的方法,有鱼
super

通过super关键字进行拓展父类构造器或方法
super作用:

①子类使用构造器constructor的时候,必须使用super关键字,用来扩展构造器

②子类同名方法会覆盖父类同名方法,使用super关键字后则可以调用到父类的同名函数

class Person{
    constructor(name){
        this.name = name;
    }
    getName(){
        console.log('我是父级类getName方法输出来的');
    }
    getAge(){
        console.log(this.age); 
    }
}
class Student extends Person{
    constructor(name,age,sex){
        super();//必须先调用super,才能使用constructor,才能使用this对象
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    getName(){
        super.getName();//调用super,才能调用父类同名函数getName
        console.log('我是子级类getName方法输出来的');
    }
}
var stu1 = new Student('有鱼',2);
stu1.getName();
// 我是父级类getName方法输出来的
// 我是子级类getName方法输出来的
static

①static关键字是类的方法

②只能通过类名来调用,不能被实例对象调用

③static方法也可以被继承

class Person{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    static getAge(){
        console.log('我是静态属性static');
    }
}
class Student extends Person{}
var stu1 = new Student('有鱼',2);
Person.getAge();//我是静态属性static
Student.getAge();//我是静态属性static
stu1.getAge();//stu1.getAge is not a function
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值