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();