ES5中的类相关/Typescript的类相关

 

ES5相关类的代码演示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    
</head>
<body>
    <div id="app">
        Box
    </div>
</body>
<script>
    //1、 es5 中的类的书写,其实类似于一个方法, 最简单的类,只有属性没有方法
    function Person() {
        this.name = "张三";
        this.age = 20;
    }

    var p = new Person();
    console.log(p.name);

    //2、构造函数和原型链中添加方法
    function Person_1() {
        this.name = "张三";  // 属性
        this.age = 20;
        this.run = function(){  // 实例方法,必须通过new的对象才能调用
            alert(this.name+"runing");
        }
    }
    var p = new Person_1();
    p.run();

    //3、通过类的原型链来添加方法和属性
    Person.prototype.sex ="male"; // 添加属性
    Person.prototype.work = function(){
        alert(this.name+'在原型链上添加方法')
    }
    var p_1 = new Person();
    p_1.work();
    // 注意原型链上的属性和方法会被多个实例共享,但是构造函数不会

    //4、 类的静态方法,上面的run、work都是实例方法,必须new后才调用
    Person.getInfo = function() {
        alert("我是类的静态方法")
    }
    Person.getInfo();  // 直接调用类的静态方法
    Person.xxxx = "类静态属性";  // 类静态属性
    console.log(Person.xxxx);

    //5、 es5 的类继承,定义个web类继承Person:原型链+对象冒充组合继承模式
    function Web(){

        Person_1.call(this);  // 对象冒充实现继承
    }

    Person_1.prototype.work = function() {
        alert("person——1 work")
    }

    var w = new Web();
    w.run(); // 继承了Person_1的方法,可以继承构造函数的属性和方法
    //w.work(); // 这里会报错,对象冒充能继承构造函数的属性和方法,但是无法实现原型链上的方法和属性

    //6、原型链上实现继承
    function Web_1() {

    }
    Web_1.prototype = new Person_1();  // 通过原型链挂载类实现继承
    var w = new Web_1();
    w.run(); // 继承了Person_1的方法,可以继承构造函数的属性和方法
    w.work(); // 没问题

    //7、 原型链实现继承的问题
    function Person_2(name,age) {
        this.name = name;  // 属性
        this.age = age;
        this.run = function(){  // 实例方法,必须通过new的对象才能调用
            alert(this.name+"runing");
        }
    }
    Person_2.prototype.sex ="male"; // 添加属性
    Person_2.prototype.work = function(){
        alert(this.name+'在工作')
    }
    var p = new Person_2('lisi',33);
    p.run();
    p.work();

    // 以上都可以实现,因为我们传入了名字和年纪,也就是说原型链继承在实例化时无法给父类传参
    function Web_2(name,age) {

    }
    Web_2.prototype = new Person_2(); // 但是我们通过原型链来实现继承就不能实时的控制name、age
    var p_2 = new Web_2('王五',45)
    p_2.run();  // undefiuned running 这里就不行了

    //8、原型链+构造函数结合实现继承
    function Web_3(name,age){
        // 这里也就是说将web类的name,age 给了父类Perons_2的构造函数this.name=name...
        Person_2.call(this,name,age); // 对象冒充继承,实例化子类可以给父类传参,    
    }
    Web_3.prototype = new Person_2();
    // Web_3.prototype = Person_2.prototype // 这样写也是可以的,效果一样
    var w = new Web_3('赵四',22);
    w.run();
    w.work();
</script>
</html>

  

Typescript中的类相关

这里我们在创建一个index.ts文件,同时创建一个html文件,其中导入index.js文件,然后大致的index.ts文件:

/* es5 中定义类
function Person(name){
    this.name = name;
    this.run = function(){
        console.log(this.name)
    }
}
*/ 

//1、 ts中的类定义,demo1
class Person {
    name:string;  // 定义类属性,前面省略了public关键字
    constructor(n:string){  // 构造函数,实例化类的时候触发的方法
        this.name = n;
    }
    run():void{
        alert(this.name)
    }
}
// 实例化类
var p = new Person('张三')  // 自动触发constructor构造函数,将n赋值给this.name,这个name就是类的共有变量
p.run();

// ts中的类定义:demo2
class Person_1 {
    name:string;  // 定义类属性,前面省略了public关键字
    constructor(name:string){  // 构造函数,实例化类的时候触发的方法
        this.name = name;
    }
    getName():string{
      return this.name;  
    }
    setName(name:string):void{
        this.name = name
    }
}

// 实例化类
var p1 = new Person_1('李四');  // 自动触发constructor构造函数,将n赋值给this.name,这个name就是类的共有变量
alert(p1.getName());
p1.setName('王麻子');
alert(p1.getName());


//2、 ts中实现继承,extends、super
class Person_2{
    name:string;
    constructor(name:string){
        this.name = name;
    }
    run():string{
        return `${this.name}在跑步`
    }
    work():string{
        return `${this.name}在工作`
    }
}

// var p3 = new Person_2("王五")
// alert(p3.run())

class Web extends Person_2 {  // 通过extends表示继承哪个类,当传入参数时先执行本身的构造函数
    constructor(name:string){
        super(name)    // 进入到构造函数后,执行父类的构造函数,传入name参数
    }
    work():string{
        return `${this.name}在工作(子)`
    }
}

var w = new Web("刘七");
alert(w.run());  // 继承了父类的方法,当然自己子类也可以扩展自己的方法

// 父类和子类的方法一致时的问题,当子类和父类重名方法时,先调用子类的方法
alert(w.work());


//3、类中的修饰符,类里面的修饰符,ts中定义属性的时候为我们提供了三种修饰符:
/*
    public(公有,类里面、子类、类外面都可以方法),属性默认都是public;
    protected(保护类型,在类里面、子类里面可以访问);
    private (私有、在类里面可以访问,子类、类外都不可以访问);
*/

class Person_3 { 
    public name:string;  // 公有属性
    protected p_name:string;  // 保护属性
    private p_x:string;   // 自能在父类中使用
    constructor(name:string){  // 构造函数,实例化类的时候触发的方法
        this.name = name;
        this.p_name = name
        this.p_x = name
    }
}

class Web1 extends Person_3 {  // 通过extends表示继承哪个类,当传入参数时先执行本身的构造函数
    constructor(name:string){
        super(name)    // 进入到构造函数后,执行父类的构造函数,传入name参数
    }
    work():string{
        return `${this.p_name}在工作(子)`  // 可以访问
    }
}
var p4 = new Person_3('xxxx')
console.log(p4.name) // 外部访问public
//console.log(p4.p_name) // 外部不能访问protected属性
var w1 = new Web1('ojbk')
console.log(w1.work());

  

Typescript类中的静态属性/方法,抽象类和多态

/* es5中的静态方法
function Person() {
    this.run1 = function() {}  // 实例方法,必须实例化才能调用
}
Person.run2 = function(){} // 静态方法,直接通过类调用

// jquery 中底层实现案例
function $(element){
    return new Base(element)
 }

 // Base对象
 function Base(element) {
     this.element = "获取到dom节点";
     this.css = function(arr, value){
         this.element.style.arr = value
     }
 }
*/

//1、ts中定义静态方法
class Person {
    public name:string;
    static sex = 'male';
    constructor(name:string){
        this.name = name;
    }
    run(){
        alert(`${this.name}在运动`)
    }
    work(){
        alert(`${this.name}在工作`)
    }
    static print() {   // 静态方法没法直接调用类里面的属性,除非时静态属性
        alert("print function " + Person.sex)  // 只能调用静态属性
    }
}
 
var p = new Person('张三四')  
p.run(); // 实例方法
Person.print(); // 静态方法


//2、 ts中的多态,多态属于继承,其实就是父类有个方法是所有实例的表象,不同的实例有不同的实现风格,比如下面的所有动物
//都吃东西,只不过每个动物各有所好
class Animal {
    name:string;
    constructor(name:string){
        this.name=name
    }
    eat(){
        console.log('吃的方法')
    }
}

class Dog extends Animal {
    constructor(name:string){
        super(name)
    }
    eat(){
        return this.name +'吃肉'
    }
}

class Cat extends Animal{
    constructor(name:string){
        super(name)
    }
    eat(){
        return this.name +'吃鱼'
    }
}

// 3、 ts中的抽象类,ts中的抽象类,它是提供其他类继承的基类,不能直接实例化,就是一种约束实例的过程把
// 用abstract关键字抽象类和抽象方法,这个关键字只能放在抽象类中

//抽象类和抽象方法用来定义标准,如必须实现eat我才让你继承并实例,否则我不认你是我的子类
abstract class Animal1 {
    public name:string;
    constructor(name:string){
        this.name = name
    }
    // 抽象方法只能出现在抽象类中
    abstract eat():any;
}

// var a = new Animal1()  // 无法实现抽象类,不能实例化
class Dog1 extends Animal1 {
    constructor(name:string){
        super(name)
    }

    // 必须实现eat抽象方法
    eat(){
        console.log(this.name+'吃粮食')
    }
}
var d = new Dog1("xiaohei")
d.eat();

  

 

posted @ 2020-05-11 18:24  独角兕大王  阅读(156)  评论(0编辑  收藏  举报