数据类型
数据类型:boolean、string、number、array、tuple(元祖类型)、enum(枚举类型)、any(任意类型)
定义数组
var arr:number[] = [11,22,33]
元祖类型
本质上属于数组的一种,用作定义混合数组
let arr:[number,string] = [123,'字符串',456]
枚举类型
一般用作状态标记
enum Flag{success = 1, error = 2}
let f:Flag = Flag.error // 定义变量f是Flag类型
console.log(f) //输出2
函数
可选参数
function getInfo(name:string, age?:number):string { // 参数age是可传参也可不传参的
return 'string';
}
默认参数
function getInfo(name:string, age:number=20):string { // 参数age默认值是20
return 'string';
}
三点运算符传参
函数重载
提一下es6里面的箭头函数
类
es5里面的类
原型链(prototype声明的)里面的属性会被多个实例共享,构造函数不会
es5里面的对象冒充实现继承
function Person() {
this.name = '张三';
this.age = 20;
this.run = function () {
alert(this.name + '在运动');
}
}
/* 原型链声明Person对象的属性和方法 */
Person.prototype.sex = '男';
Person.prototype.work = function () {
alert(this.name + '在工作');
}
// web类继承Person类,原型链+对象冒充的组合继承模式
function Web () {
Person.call(this); // 对象冒充实现继承
}
var w = new Web();
w.run(); // 成功! 对象冒充可以继承构造函数里面的方法和属性
w.work(); // 失败!对象冒充不可以继承原型链里面的属性和方法
es5里面的原型链实现继承
function Person() {
this.name = '张三';
this.age = 20;
this.run = function () {
alert(this.name + '在运动');
}
}
/* 原型链声明Person对象的属性和方法 */
Person.prototype.sex = '男';
Person.prototype.work = function () {
alert(this.name + '在工作');
}
// web类继承Person类,原型链继承模式
function Web () {
}
Web.prototype = new Person(); // 原型链继承
var w = new Web();
w.run(); // 成功! 原型链继承可以继承构造函数里面的方法和属性
w.work(); // 成功!原型链继承可以继承原型链里面的属性和方法
es5原型链继承的问题
es5原型链继承时,无法给在实例化子类的时候无法给父类的构造函数传参
function Person(name, age) {
this.name = name;
this.age = age;
this.run = function () {
alert(this.name + '在运动');
}
}
// web类继承Person类,原型链继承模式
function Web (name, age) {
}
Web.prototype = new Person(); // 原型链继承
var w = new Web('张三', 20);
w.run(); // 成功! 但输出的是 undefined在运动,即传递给Web对象的参数无法一起传递到父对象的构造函数中
es5解决原型链继承的问题,对象冒充加原型链继承混合模式
解决es5原型链继承时,无法给在实例化子类的时候无法给父类的构造函数传参的问题,即加入对象冒充
function Person(name, age) {
this.name = name;
this.age = age;
this.run = function () {
alert(this.name + '在运动');
}
}
// web类继承Person类,原型链继承模式
function Web (name, age) {
Person.call(this, name, age) // 对象冒充,实例化时可以给父类传参
}
Web.prototype = new Person(); // 原型链继承
// Web.prototype = Person.prototype; 这样写也可以,因为对象冒充已经继承了父类构造函数中的方法与属性,原型链只需要再继承父类方法中的原型链属性和方法即可
var w = new Web('张三', 20);
w.run(); // 成功! 输出的是 张三在运动,即传递给Web对象的参数一起传递到了父对象的构造函数中
typeScript里面的类
class Person { // 注意,Person后面没有()
name:string; // 属性,前面省略了public关键词
constructor(n:string) { // 构造函数
this.name = n ;
}
getName:string() {
return this.name;
}
}
var p = new Person('张三');
p.getName() // 张三
typeScript的继承
关键字是extends和super和java差不多
class Person { // 注意,Person后面没有()
name:string; // 属性,前面省略了public关键词
constructor(n:string) { // 构造函数
this.name = n ;
}
getName:string() {
return this.name;
}
work() {
alert(this.name + '在工作--父类' )
}
}
// Web类继承Person类
class Web extends Person {
constructor(name:string) {
super(name) // 使用父类的构造方法
}
work() {
alert(this.name + '在工作--子类' ) // 能成功取到name
}
}
var w = new Web('张三');
w.getName() // 张三
w.work() //注意,此处继承特性与java一样,即当父类和子类有同样的方法名时,首先调用子类的方法,即输出是 张三在工作--子类
跟java很像的类修饰符
jquery $()的实质
function $(element) {
return new Base(element) // 实例化对象
}
$.get = function() { // $对象的静态方法
}
function Base(element) {
this.element = 获取dom节点; // 此处代表获取到dom节点
this.css = function(arr, value) {
this.element.style.arr = value; // 写入css
}
}
$('box').css('color', 'red) // jquer实际上是调用上面定义的对象,将‘box’作为参数传进构造函数,相当于base对象调用它的css方法
$.get('url', function() { // 相当于调用静态方法
})
typeScript的静态方法
与java一样使用static关键字声明静态方法
class Person { // 注意,Person后面没有()
name:string; // 属性,前面省略了public关键词
static age:number = 20; // 声明静态属性
constructor(n:string) { // 构造函数
this.name = n ;
}
getName:string() {
return this.name;
}
static print:void() { // 声明静态方法
alert('静态方法')
}
}
var p = new Person('张三');
p.getName() // 张三,此处是调用实例方法
Person.print() // 直接用类名调用静态方法
Person.age // 调用静态属性
TS的多态
多态:父类定义一个方法不实现,让继承它的子类去实现,每一个子类有不同的实现,多态隶属于继承
class Animal {
name:string;
constructor(name:string) {
this.name = name;
}
eat() { // 后面两个类都继承了eat方法,但都重写了eat方法,使各个类有各自的特性,这就是多态
console.log('父类吃的方法')
}
}
class Dog extends Animal {
constructor(name:string) {
super(name)
}
eat() { // 多态体现1,狗有狗的吃方法
return this.name + '吃肉'
}
}
class Cat extends Animal {
constructor(name:string) {
super(name)
}
eat() { // 多态体现2,猫有猫的吃方法
return this.name + '吃老鼠'
}
}
注意重写与重载的区别:
重写:子类继承父类的方法后重新写该方法,使该方法有自己类的特性
重载: 同一个类里面的同名方法,但参数类型或者个数不一样
抽象类与抽象方法
TS中的抽象类,是其他继承类的基类,不能直接被实例化,就是说这个类是不能被new关键字实例化的,它的作用就是声明一个类有该属性和方法,然后让别的类去继承。例如人类是一个很大的类,所有人有一些共同的特性,例如都能拉尿,但人这个类一般不直接实例到具体的某一个人,而是让它的子类去实例化。例如男类和女类都继承了人类,也继承了拉尿的方法,但拉尿的方法的具体实现不一样(嘻嘻)。
抽象类和方法是用来定义标准,它表示这个类和它的子类必须要有该方法
注意:抽象方法只能放在抽象类里面
```js
abstract class Animal { // abstract声明抽象类
name:string;
constructor(name:string) {
this.name = name;
}
abstract eat():any; // 抽象方法,所以继承这个类的子类都必须重写这个方法,抽象方法只能放在抽象类里面
}
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 + '吃老鼠'
}
}
接口(interface)
接口的本质是对实现接口的方法进行约束
属性接口
属性接口:接口包含的都是一些属性
interface FullName { // 声明一个属性接口,这个接口包含的都是一些属性。实现这个接口的方法必须有firstName和lastName,且都是string类型
firstName:string;
secondName:string;
}
function printName(name:FullName) { // 这个方法实现了FullName接口,必须接受该接口的规范
console.log(name.firstName + '--' + name.secondName);
}
var obj = {
age:20,
firstName: '张'
secondName: '三'
};
printName(obj) // 调用printName方法,将obj对象作为参数,该对象包含firstName和lastName,满足接口规范
可选属性接口
方法实现该接口时,接口中的一些属性可有也可没有
interface FullName { // 声明一个属性接口,这个接口包含的都是一些属性。实现这个接口的方法必须有firstName,而lastName可有可无,且都是string类型
firstName:string;
secondName?:string; // 可选属性
}
function printName(name:FullName) { // 这个方法实现了FullName接口,必须接受该接口的规范
console.log(name.firstName + '--' + name.secondName);
}
printName({
firstName: '张'
}) // 调用printName方法,对象包含firstName即可满足接口规范
以接口的方式来看ajax就很好理解了
我们常用的ajax
$.ajax({
type: "GET",
url: "test.json",
data: {username: $("username").val(), content:$("#content").val()},
dataType: "json"
});
实际上ajax就是一个实现了接口规范的方法
interface Config { // 声明接口
type:string,
url:string;
data?:string;
dataType:string;
}
function ajax(config:Config) {
var xhr = new XMLHttpRequest(); // 用作建立http连接
xhr.open(config.type,config.url,true);
xhr.send(config.data);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
console.log('成功');
if(config.dataType == 'json') {
JSON.parse(xhr.responseText)
}else{
console.log(xhr.responseText)
}
}
}
}
ajax({ // 调用方法
type: 'get',
url: 'http://www.baidu.com',
dataType: 'JSON'
})
函数类型接口
函数类型接口:对方法传入的参数以及返回值进行约束
interface encrypt{
(key:string,value:string):string; // 约束参数必须要有key和value,且函数的返回值必须是string
}
var md5:encrypt = function(key:string, value:string):string {
return key + value;
}
可索引接口
可索引接口主要是对数组、对象的约束,并不常用
interface userArr{ // 对数组的约束
// [index:number]:any
[index:number]:string //实现这个接口的数组的索引必须是number而且数组的元素必须是string
}
var arr:UserArr = ['aaa', 'bbb'] //数组arr实现userArr接口
interface userObj{ // 对对象的约束
// [index:number]:any
[index:string]:string //实现这个接口的数组的索引必须是string而且数组的元素必须是string
}
var arr:userObj = [name: '张三'] //数组arr实现userObj接口
类类型接口
类类型接口主要是对类的约束,和抽象类有点相似
interface Animal { // 规定实现这个接口的类必须要有name属性和eat方法,且无返回
name:string;
eat(str:string):void;
}
class Dog implements Animal {
name:string;
constructor(name:string) {
this.name = name;
}
eat() { // eat方法没有按照接口有参数也不会报错
console.log(this.name + '吃东西')
}
}
var d = new Dog('小黑');
d.eat(); // 能成功运行,输出 小黑吃东西
接口扩展
接口扩展:接口可以继承接口
interface Animal{
eat():void;
}
interface Person extends Animal{ // 接口继承接口
work():void;
}
class Web implements Person{
public name:string;
constructor(name:string) {
this.name = name
}
/* 必须将两个接口的方法都实现 */
eat() {
console.log(this.name + '喜欢吃馒头')
}
work() {
console.log(this.name + '写代码');
}
}
泛型
泛型可以支持不特定的数据类型,要求传入的参数和返回的参数一致
function getData<T>(value:T):T{ // T表示泛型,具体是什么类型是调用方法时传递过来的参数决定
return value
}
getData<number>(123); // 调用getData方法,此时泛型T代表number
类的泛型
class MinClass<T> {
public list:T[] = [];
add(value:T):void {
this.list.push(value);
}
min():T {
var minNum = this.list[0];
for(var i=0;i<this.list.length;i++) {
if(minNum > this.list[i]) {
minNum = this.list[i];
}
}
return minNum;
}
}
var m1 = new MinClass<number>(); // 实例化类,且指定了泛型T代表的类型是number
m1.add(1);
m1.add(3);
m1.add(7);
console.log(m1.min()) // 输出最小值1
var m2 = new MinClass<string>(); // 实例化类,且指定了泛型T代表的类型是string
m2.add('a');
m2.add('v');
m2.add('c');
console.log(m2.min()) // 输出最小字母a
泛型接口
interface Config{
<T>(value:T):T; // 定义泛型接口
}
var getData:Config = function<T>(value:T):T{
return value;
}
getData<string>('张三') // 确定泛型T代表的是string
另一种泛型接口的写法
interface Config<T>{
(value:T):T; // 定义泛型接口
}
function getData<T>(value:T):T {
return value;
}
var myGetData:Config<string> = getData; // 定义一个变量,类型是Config接口规定的类型,而且确定泛型T代表的是string类型,并将函数getData赋予这个变量
myGetData('张三') // 调用函数
\