dedecms 网站访问量,安徽省建设厅建筑信息网,互联网上市公司排名,全渠道营销成功案例文章目录 一、类1.1 基本示例1.2 继承1.3 实例成员访问修饰符1.3.1 public 开放的1.3.2 private 私有的1.3.3 protected 受保护的1.3.4 readonly 只读的1.3.5 在参数中使用修饰符 1.4 属性的存#xff08;get#xff09;取#xff08;set#xff09;器1.5 静态成员 二、函数… 文章目录 一、类1.1 基本示例1.2 继承1.3 实例成员访问修饰符1.3.1 public 开放的1.3.2 private 私有的1.3.3 protected 受保护的1.3.4 readonly 只读的1.3.5 在参数中使用修饰符 1.4 属性的存get取set器1.5 静态成员 二、函数2.1 函数参数2.2 箭头函数 三、for-of 循环四、类型推断Type Inference五、模块5.1 概念5.2 模块通信导出5.3 模块通信导入 一、类
1.1 基本示例
class Person {name: string;age: number;constructor(name: string, age: number) {this.name name;this.age age;}sayHello() {console.log(this.name);}
}let zs: Person new Person(张三, 18);
1.2 继承
class Animal {move(distanceInMeters: number 0) {console.log(Animal moved ${distanceInMeters}m.);}
}class Dog extends Animal {bark() {console.log(Woof! Woof!);}
}const dog new Dog();
dog.bark();
dog.move(10);
dog.bark();这个例子展示了最基本的继承类从基类中继承了属性和方法。 这里 Dog是一个 派生类它派生自 Animal 基类通过 extends关键字。 派生类通常被称作 子类基类通常被称作 超类。
因为 Dog继承了 Animal的功能因此我们可以创建一个 Dog的实例它能够 bark()和 move()。
下面是一个更复杂的例子
class Animal {name: string;constructor(theName: string) { this.name theName; }move(distanceInMeters: number 0) {console.log(${this.name} moved ${distanceInMeters}m.);}
}class Snake extends Animal {constructor(name: string) { super(name); }move(distanceInMeters 5) {console.log(Slithering...);super.move(distanceInMeters);}
}class Horse extends Animal {constructor(name: string) { super(name); }move(distanceInMeters 45) {console.log(Galloping...);super.move(distanceInMeters);}
}let sam new Snake(Sammy the Python);
let tom: Animal new Horse(Tommy the Palomino);sam.move();
tom.move(34);与前一个例子的不同点是派生类包含了一个构造函数它 必须调用 super()它会执行基类的构造函数。 而且在构造函数里访问 this的属性之前我们 一定要调用 super()。 这个是TypeScript强制执行的一条重要规则。
这个例子演示了如何在子类里可以重写父类的方法。 Snake类和 Horse类都创建了 move方法它们重写了从Animal继承来的 move方法使得 move方法根据不同的类而具有不同的功能。 注意即使 tom被声明为Animal类型但因为它的值是 Horse调用 tom.move(34)时它会调用 Horse里重写的方法
Slithering...
Sammy the Python moved 5m.
Galloping...
Tommy the Palomino moved 34m.1.3 实例成员访问修饰符
1.3.1 public 开放的
默认为 public
class Animal {public name: string;public constructor(theName: string) { this.name theName; }public move(distanceInMeters: number) {console.log(${this.name} moved ${distanceInMeters}m.);}
}1.3.2 private 私有的
不能被外部访问只能在类的内部访问使用私有成员不会被继承
class Person {public name: string;public age: number 18;private type: string humanpublic constructor (name, age) {this.name namethis.age age}
}1.3.3 protected 受保护的
和 private 类似但是可以被继承
class Person {protected name: string;constructor(name: string) { this.name name; }
}class Employee extends Person {private department: string;constructor(name: string, department: string) {super(name)this.department department;}public getElevatorPitch() {return Hello, my name is ${this.name} and I work in ${this.department}.;}
}let howard new Employee(Howard, Sales);
console.log(howard.getElevatorPitch());
console.log(howard.name); // 错误注意我们不能在 Person类外使用 name但是我们仍然可以通过 Employee类的实例方法访问因为Employee是由 Person派生而来的。
1.3.4 readonly 只读的
1.3.5 在参数中使用修饰符
在上面的例子中我们不得不定义一个受保护的成员 name和一个构造函数参数 theName在 Person类里并且立刻给 name和 theName赋值。 这种情况经常会遇到。 参数属性可以方便地让我们在一个地方定义并初始化一个成员。
class Person {name: string;age: number;constructor(name: string, age: number) {this.name name;this.age age;}
}可以简写为
class Person {constructor(public name: string, public age: number) {}
}1.4 属性的存get取set器
let passcode secret passcode;class Employee {// 私有成员外部无法访问private _fullName: string;// 当访问 实例.fullName 的时候会调用 get 方法get fullName(): string {return this._fullName;}// 当对 实例.fullName xxx 赋值的时候会调用 set 方法set fullName(newName: string) {if (passcode passcode secret passcode) {this._fullName newName;}else {console.log(Error: Unauthorized update of employee!);}}
}let employee new Employee();
employee.fullName Bob Smith;
if (employee.fullName) {alert(employee.fullName);
}1.5 静态成员
不需要实例化访问的成员称之为静态成员即只能被类访问的成员static 关键字
class Grid {static origin {x: 0, y: 0};calculateDistanceFromOrigin(point: {x: number; y: number;}) {let xDist (point.x - Grid.origin.x);let yDist (point.y - Grid.origin.y);return Math.sqrt(xDist * xDist yDist * yDist) / this.scale;}constructor (public scale: number) { }
}let grid1 new Grid(1.0); // 1x scale
let grid2 new Grid(5.0); // 5x scaleconsole.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));二、函数
2.1 函数参数
参数及返回值类型
function add(x: number, y: number): number {return x y
}可选参数
function add(x: number, y?: number): number {return x 10
}默认参数
function add(x: number, y: number 20): number {return x y
}剩余参数
function sum(...args: number[]): number {let ret: number 0args.forEach((item: number): void {ret item})return ret
}sum(1, 2, 3)2.2 箭头函数
基本示例
let add (x: number, y: number): number x y三、for-of 循环
for 循环forEach 不支持 break for in 会把数组当作对象来遍历 for of 支持 break
四、类型推断Type Inference
TypeScript 编译器会根据一些简单的规则来推断你定义的变量的类型
当你没有标明变量的类型时编译器会将变量的初始值作为该变量的类型
let num 3
//此时我未标注 num 变量的类型 初始值为数字类型 变量num为数字类型
let str string
//此时我未标注 str 变量的类型 初始值为字符串类型 变量str为字符串类型
当然类型推断不仅仅发生在简单数据类型上面复杂数据类型上依然可以被TypeScript编译器进行推断
let arr [one,two,three]
//此时未标注 arr 数组中的每个元素类型 初始值为字符串则相当于
//let arr : string[]//但如果数组中没有元素为空数组则类型为 neverlet obj {a:1,b:2}
//此时未标注对象内的数据类型默认为初始值为数字类型
//let obj : {a:number,b:number}//不仅如此ts编译器还会推断函数的返回值类型
const fun (a:number,b:number) {retrun a b;
}
//const fun (a:number,b:numer) number
但在使用函数返回值类型推断时在编写函数内部的代码就失去了函数返回值类型检测功能使用函数返回值的类型需要明确的指定
正常情况下TypeScirpt编译器时可以推断出变量类型的开发者不需要编写类型注释但在TypeScirpt编译器不能正常推断类型时开发者需要编写类型注释 第一种情况 如果一个变量被声明后没用被立即初始化那么编译器将不能正确推断出它的类型将被赋予any类型 let anything
//此时变量未被及时初始化编译器默认它为any类型let anything :any 第二种情况 当被调用的函数的返回值为any类型的时候应该使用类型注释来声明它的类型 let json {name:张三};
let person JSON.parse(json);
//let json:string
//let person:any let person:{name:string} 第三种情况 当变量有可能有多个类型时 let num [-10,-1,20]
//target bollean|number
let target falsefor(let i0;inum.length;i){if(num[i]0){//不能将number类型分配给bollean类型target num[i];}
} 第四种情况 函数的参数必须标注类型TypeScript并不能推断函数参数的类型
五、模块
5.1 概念
5.2 模块通信导出
export default xxxexport const foo: string bar;
export const bar: string foo;5.3 模块通信导入
// 加载默认成员
import xxx from 模块标识// 按需加载模块成员
import {foo, bar} from 模块