TypeScript前期准备:
需要安装 node npm
ios安装node指令 brow install nodejs
还需要安装homebrew
TypeScript
面向对象语法(Prototype,Function,Object)
class interface自己实现了类接口
类型检查(静态 ,强类型)
TypeScript 优点
1.面向对象
2.类型检查 更好避免bug
3.自带文档特性
4.IDE或编辑工具良好支持(自动提示在 做大项目代码量多的时候很方便)
5.自动编译时能提前发现错误
TypeScript = TypeScript + type +(some other stuff)主要是类型不同
TypeScript 需要编译成JavaScript
编译指令:
tsc + 文件名.js
类型的定义
三种定义类型方法=> var let const
var :函数级作用域(怎么理解 例子如下):
if(true){var i = 1;}
console.log(i) 可以输出 i = 1
if(true){let i = 1;}
console.log(i) 直接报错 let找不到i
let:限制变量的作用范围
const:定义常量
其中var可重复定义 let 不可以重复定义 定义好的类型都不可以改变
例如:var a : number;
a="hello" 直接报错
定义数组的两种方法:
1.let myArr : number [] = [1,2,3]
2.let myArr : Array<boolean>=[false,false,true];
元组 yuple
跟数组差不多 但是里面的元素可以多个类型
编译出来的JavaScript也是数组
元素个数是固定的 顺序不能变
定义元组
let my_tuple:[string,number]=['abc',123]
箭头函数
const add = (a:number,b:number) =>{
return a+b;
}
let sum = add(10,20);
console.log(sum);
等同于:
function add (a:number,b:number){
return a+b;
}
返回值类型
const add = (a:number,b:number):number//(此处规定函数返回值类型) =>{
return a+b;
}
let sum = add(10,20);
console.log(sum.toFixed(2));//保留两位小数 编译后=30.00
const add = (a:number,b:number):String=>{
return a.toString()+b.toString();
}
let sum = add(10,20);
console.log(sum.substr(0,3));//编译结果为102,截取3个字符串长度
函数指定返回值的类型
可以让调用的地方知道是什么类型的返回值,以便进行处理
默认参数(=)
可选参数(?) //赋值方式一般放到参数后面,默认的参数可以不指定类型,会自动判断和计算
any的使用
let a :any;//可以为任意类型
a = 10 ;
a = "abcd";
a = [1,2];
const log = (value:any)=>{
if(typeof value === 'number'){
return 'your name is ${value}';
}
if(typeof value === 'String'){
return 'your name is ${value}';
}
therow new Error('Expected String or number ,got ${value};')
};
console.log(log('abc')); //输出 your name is abc
console.log(log(123)); //输出 your name is 123
console.log(log([1,2])); //输出 设定的异常
typescript的写法
function isNumeber(value:any):value is number{
return typeof value === "number";
}
function isNumeber(value:any):value is String{
return typeof value === "String";
}
undefined 和 null 有自己的类型为 undefind和null,默认情况是所有类的子集
如果编译时指令为 tsc --strictNullchecks index.js 会报错,默认的情况就失去效果
类Class
class (模板) new 对象
数 据 (data) 行为 (action)
行为可能是对数据进行操作
//模板
Class Person{
//定义两个数据内容
firstName:String;
lastName : String;
}
//生成一个对象
let aPerson = new Person();
//设置firstName的内容
aPerson.firstName = "hello"
//读取firstName的内容
console.log(aPerson.firstName);
编译后输出:hello
}
//例子
Class Movies{
name:String;
play_count:number;
created_at:String;
time:String;
}
let m = new Movies();
m.name = "这是一个例子"
console.log(m.name);
编译后输出:这是一个例子
}
面向对象概念
Class 模板
/ | \
/ | \
/ | \
/ | \
真实Object 真实Object 真实Object
| |
| |
宝马(车) 奥迪(车)
class class
//例子代码
Class Person{
//定义了两个数据内容
firstName:String;
lastName : String;
great(){
console.log('hi');
}
othergreet(){
this.greet();
console.log('*****');
}
}
//继承了父类的数据和行为,就是属性和方法
//他的父类是Person
Class Programmer extends Person{
greet(){
console.log('hello world');
}
//super代表父类
greetLikeNormalPeople(){
super.greet();
}
}
let aPregrammer:Preson = new Programmer();
//let aPregrammer:Programmer = new Programmer();
调用方法时,先找本身对象的方法,如果没有,会找父类的方法
aProgrammer.greet();
aProgrammer.greetLikeNormalPeople();
aProgrammer.othergreet();
//生成一个对象
let aPerson = new Person();
设置firstName内容
aPerson.firstName = "hello";
aPerson.othergreet();
//读取firstName的内容
console.log(aPerson.firstName);
}
三个修饰符对成员属性和方法进行修饰
public 公有的 任何属性和方法都可以在生成的对象中调用,继承的对象也能调用 默认是public
private 私有的 只有在内部对象内才能访问,生成的对象调用不了,要调用的私有方法和属性可以在class里
定义public的方法来调用
继承的对象也是不能够直接用生成的对象来访问
子类继承的时候也可以继承私有属性和方法 也是要通过继承过来的public方法来调用
protected 受保护的,只有在内部class还有子类能访问 生成对象访问不了 要调用私有方法和属性 可以在class里定义
public的方法来调用
继承的对象也是不能够直接用生成的对象来访问
子类继承的时候也可以继承私有属性和方法 也是要通过继承过来的public方法和自己定义的public方法在外部调用
(这点和其他语言有些不一样)
内部调用:class里面的方法
外部调用:生成对象的时候
private protected 区别 在子类的时候
1.继承方法一样的表现形式 可以内部访问继承过来的public private protected 属性和方法
2.子类定义的方法 只能通过访问继承过来的public和protected的属性和方法 不能访问继承过来的private属性和方法
如果要访问父类的private属性和方法 可以通过继承过来的public private protected方法在内部访问
//代码例子
Class Person{
private firstName:String;
getfirstName(){
console.log(this.firstName);//暴露一个方法
}
setfirstName(firstName){
this.firstName = firstName;
}
}
let aPerson = new Person();
aPerson.setfirstName('abc');
aPerson.getfirstName();
编译后结果为:abc
或
private SayHi(){
console.log('abcd');
}
public CallSayHi(){
this.SayHi();
console.log('1234');
}
aPerson.CallSayHi();
编译输出结果为:abcd1234
构造方法constructor
如果声明为protected 或private 当前类不能new
当父类声明为protected 子类重写constructor方法可以new(子类可以new)
如果父类声明为private子类不能new和extends
super()在constructor方法中是调用父类的构造方法,必要时要传入参数
作用
1.当不想被实例化,而只想让子类继承后实例化 可以声明为protected
2.都不想让子类和父类实例化或继承可以声明为private
3.一般情况下声明为public(或不写)
静态属性和方法 static
通过类似Person加方法名或属性来调用(比如Person.age)
默认是声明为public
如果是protected 或private的话 当前类都不能调用,通过public的静态方法来调用
如果父类是protected 或private的话 子类也能继承所有的静态方法和属性
子类还是不能调用protected 或private的方法和属性只能通过继承的public的方法来调用
子类定义的方法(public)只有是父类定义为public或protected的才能访问,private的不能访问
Readonly 只读属性
readonly name :String = 'abc'
只读属性,不能修改相当于常量
枚举类型
enum DaysofTheWeek{
SUN,MON,TUE,WED,THU,FRT,SAT
}
let day : DaysofTheWeek;
day = DaysofTheWeek.MON;
console.log(day);
编译输出:1
如果给一个默认值例如SUM=100,那么就变成从100开始
enum:
它的值是数字序列,从0开始
代码可读性强
用于下拉框等应用
Ts-node nodemon
Ts-node 直接执行ts格式文件
安装指令:npm install -g ts-node 全局安装
使用格式:ts-node script.js
nodemon 监控js文件改变,自动运行
安装指令:npm install -g nodemon 全局安装
使用格式:nodemon --exec ts-node./index.js
接口interface
接口规定了如何设计 就是一些规范
电脑上的usb接口 如果要实现鼠标 u盘等不同的电器都可以接入在
设计时必须按照usb接口来设计
和java一样 都是为了解决类的单继承问题
类实现接口
代码示例如下:
//支付接口 实现接口 微信支付 支付宝支付
interface Pay{
post():void;
}
//可能会发送http请求 真正支付的请求
const do_Pay=(Pay:pay)=>{
pay.post()
}
//微信支付
class WePay inplement pay{
//调用微信支付的接口
post(){}
}
//支付宝支付
class AliPay implement pay{
//调用支付宝的接口
post(){}
}
//其他支付接口
let we_Pay:pay=new WePay();
let ali_Pay:pay=new AliPay();
//微信支付 取值
do_Pay(We_Pay);
//支付宝支付 取值
do_Pay(Ali_Pay);
下列代码可理解为匿名函数
interface PrintCallback{
(success=boolean):void
}
let PrintCallback:PrintCallback;
PrintCallback=(suc:boolean):void=>{}
类型断言
在typescript中类型断言是告诉编译器变量是哪个类型的方式
跟类型转换有点类似 但只用于编译时期
类型转换是在运行时期强制转化类型
示例:
//x代表可以是任何类型比如字符串number之类的
//编译器可能不能明确知道x是那种类型
let x :any="111";
//<String>表示把x断言成字符串类型就是告诉编译器要把x当成字符串 才有这个函数
let s =(<number>x);
console.log(typeof s);
示例代码如下:
inter Person{
name:String;
age:number:
}
//一种写法
let Person1 = <Person>{
name="abc";
age=27;
}
//另一种写法
let Person ={} as Person; //这里的as 更好的明确类型和类型里面的结构
Person.name="abc";
Person.age=27;
接口继承
class ComPonent{
private width : number;
private height : number;
Constructor(width : number,height : number){
this.width=width;
this.height=height;
}
display():void{
console.log(this.height);
}
}
接口继承类
继承类的方法和属性 但可以不用实现方法
也可以定义自己的方法和属性
interface widget extends Component{
hide():void;
}
class Button extends component implements widget{
hide():void{
console.log('hiding');
}
}
let w:widget=new Button(1,2);
console.log(w);
w.display();
w.hide();
indexable.Types语法: 索引性类型
[propName:String]:any
interface states{
[index:string]:boolean;
这是key值 key可以是数字 字符串
let s:states={
'enabled':true,'maximized':fase
}
}
interface states1 {
[index:number]:boolean; 这种方式定义的数组没有push length join
等属性和方法有局限性
let s1:states1=[true,fase,true];
let s2:number[]=[1,2,3] 这种方式定义的数组可以正常使用push length join
索引参数一定是string或mnumber
let s2:后面的
string等于对象
number等于数组
}
处理数组列表结构
根据
let todos = [
{
"userId":1,
"id":1,
"title":"abc",
"completed":fase
}
]
...数组2,
...数组3,
可以这样写
interface Todo{
{
"userId":number,
"id":number,
"title":"string",
"completed":boolean
}
}
let todos 改成
let todos:Todo[]:{
...数组,
}
抽象类
abstract class person{
name:String; //不能实例化
constructor(name:String){
this.name=name;
}
display():void{
console.log(this.name);
}
}
Class Employee extends Person{
name:String;
empcode:number;
constructor(name:String,code:number){
super(); //必须调用super
this.name=name;
this.empcode=code;
}
//必须实现抽象的方法
find(name:String):person{
return new Employee(name:())
}
}
Accessors
class Person{
private _name:String;
private _age:number;
constructor(name:String,age:number){
this._name=name;
this._age=age:
}
//读取
getName():String{
return this._name;
}
//设置
setName(name:String):void{
this._name=name;
}
get name():String{
return this._name;
}
set name(name:String){
this._name=name;
}
}
let p :Person = new Person("abc",29);
//输出name
console.log(p.name);
//修改name
p.mame="test";
console.log(p);