ElementUI说明ElementUI是饿了么团队基于Vue开发的前端框架,使用方便简单官方文档:https://element.eleme.cn/#/zh-CN/component推荐使用npm的方式安装,它能更好地和webpack打包工具配合使用。npmielement-ui-S引入Element操作main.js完整引入打包体积会变的大一点importVuefrom'vue';importElementUIfrom'element-ui';import'element-ui/lib/theme-chalk/index.css';importAppfrom'./App.vue';Vue.use(ElementUI);#使用ElementUInewVue({el:'#app',render:h=>h(App)});按照需要引入借助babel-plugin-component我们可以只引入需要的组件,以达到减小项目体积的目的。npminstallbabel-plugin-component-D修改.babelrc文件{"presets":[["es2015",{"modules":false}]],"plugins":[["component",{"libraryName":"element-ui","styleLibraryName":"theme-chalk"}]]}接下来就能安装需要引入组件importVuefrom'vue';import{Button,Select}from'element-ui';importAppfrom'./App.vue';Vue.component(Button.name,Button);Vue.component(Select.name,Select);/*或写为*Vue.use(Button)*Vue.use(Select)*/newVue({el:'#app',render:h=>h(App)});官网有个完整单独组件引入https://element.eleme.cn/#/zh-CN/component/quickstart现在基于Element的环境开发搭建完毕
安装安装Vue//npminstall-gvue-g全局安装npminstall-gvue安装Vue-cli安装之后,你就可以在命令行中使用vue命令。npminstall-g@vue/cli//npmupdate-g@vue/cli全局升级npminstall-g@vue/cli-init//使用vue-cli相关模板创建项目这里使用webpackvue-V//查看版本创建一个项目运行下面命令,使用Vue-cli创建webpack模板项目vueinitwebpackhello_worldD:\HBuilderProjects>vueinitwebpackhello_world?Projectnamehello_world#项目名称?ProjectdescriptionAVue.jsproject#项目描述?Authorbigdataboy#项目作者?Vuebuild(Usearrowkeys)>Runtime+Compiler:recommendedformostusersRuntime-only:about6KBlightermin+gzip,buttemplates(oranyVue-specificHTML)areONLYallowedin.vuefiles-renderfunctionsarerequiredelsewhere然后四个No,选择npm安装依赖,等待下载Installvue-router?No#路由不安装?UseESLinttolintyourcode?No#代码检测不安装?SetupunittestsNo#测试不安装?Setupe2etestswithNightwatch?No#调试不安装?Shouldwerun`npminstall`foryouaftertheprojecthasbeencreated?(recommended)npm运行ui界面创建web-ui界面不止能创建项目,还能管理项目,依赖,插件,配置打包等vueui手动选择全部都不选选择Vue2目录介绍启动&打包npmrundev//开发环境打包,主要用于测试,不会生成打包文件npmrunstart//与上一个相同,最终调用的还是上一个命令npmrunbuild//打包
说明插槽:可以理解为占一块位置,然后可以插入组件,当有数据传入待插入组件时,再展示出来,没有数据时,插槽位置为空有数据时没有数时注册组件//留有插槽的组件模板里关联有待插入组件Vue.component('item',{template:'<div>\<slotname="h4-title"></slot>\<ul>\<slotname="li-slot"></slot>\</ul>\</div>'})//待插入组件Vue.component('h4-title',{props:['title'],template:'<h4>{{title}}</h4>'})//待插入组件Vue.component('li-slot',{props:['item'],template:'<li>{{item}}</li>'})使用item组件<item><!--插槽与待插入组件关联--><h4-titleslot="h4-title":title="title"></h4-title><li-slotslot="li-slot"v-for="(item,index)initems":item='item'></li-slot></item>全部代码<!DOCTYPEhtml><html><head><metacharset="utf-8"/><title></title><!--<scriptsrc="https://unpkg.com/vue@next"></script>--><scriptsrc="js/v2.6.10/vue.min.js"type="text/javascript"charset="utf-8"></script></head><body><divid="app"><item><!--插槽与待插入组件关联--><h4-titleslot="h4-title":title="title"></h4-title><li-slotslot="li-slot"v-for="(item,index)initems":item='item'></li-slot></item></div><script>Vue.component('item',{template:'<div>\<slotname="h4-title"></slot>\<ul>\<slotname="li-slot"></slot>\</ul>\</div>'})Vue.component('h4-title',{props:['title'],template:'<h4>{{title}}</h4>'})Vue.component('li-slot',{props:['item'],template:'<li>{{item}}</li>'})varvue=newVue({el:'#app',data:{counter:'hello',title:'标题',items:['AA','BB','CC']}})</script></body></html>
jsvmp特点jsvmp有一个最大的特点,就是有一长串字符串._$jsvmprt(...),算法代码的具体细节都在这个一节长字符串里,所有在算法的扣取上就很不友好,本案例采取补环境的方式实现。(glb="undefined"==typeofwindow?global:window)._$jsvmprt(.....)逻辑分析定位加密入口添加XHR断点,然后向下滑动,断点短住搜索_signature,在关键位置下断点,然后在刷新页面断点位置r变量,来自于S(n,e)函数计算,该S函数就是入口函数分析加密得值逻辑进入S函数,分析这一段逻辑,其实调用的就是//o是{'url':'xxxx'}window.byted_acrawler.sign(o)进入window.byted_acrawler.sign函数,来到acrawler.js文件,也就是jsvmp的Js文件补环境把acrawler.js文件全部复制下来,代码起始有一句(varglb;glb="undefined"==typeofwindow?global:window),这是检查当前是什么环境的,是node还是浏览器有两种处理办法使用jsdom补充window使用window=global当然还有其他更好的方式,这里采用第二次这样就和浏览器一样了加上一个输出,尝试使用node,浏览器执行,查看两者的区别浏览器正常得值,node报错,说明node缺少一些条件在浏览器添加条件断点,查看referrer是什么//referrer来自于document,继续添加环境document={referrer:''}node继续执行,发现没有sign,说明node还被检查着经过分析,发现这些代码,exports、module,这是node才存在的东西,直接改成undefined当然也有更好的方式直接过滤这些特征//nodetrue浏览器false"undefined"!=typeofexports//nodetrue浏览器false"undefined"!=typeofmodule继续执行,缺少href,就根据浏览器的插装输出补充就好了然后是缺少‘protocol’location={href:'',protocol:'https:'}然后是缺少userAgentnavigator={userAgent:'Mozilla/5.0(WindowsNT10.0;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/86.0.4240.198Safari/537.36'}再次执行,出现结果因为校验的不严格,所以这个短Cookie也是可以过的,长Cookie需要添加一些Cookie才行长Cookie需要加上其他的Cookie,这个cookie位置需要靠后,不然会被清空如果是自己写的环境框架,就不需要担心cookie的位置为了稳定,请求头部还需要带一个随机Cookie完整结构
内置对象JavaScript中有很多内置对象,它们可以直接在TypeScript中当做定义好了的类型。内置对象是指根据标准在全局作用域(Global)上存在的对象。这里的标准是指ECMAScript和其他环境(比如DOM)的标准。ECMAScript的内置对象Boolean、Number、String、Date、RegExp、Errorletb:Boolean=newBoolean(1)letn:Number=newNumber(true)lets:String=newString('abc')letd:Date=newDate()letr:RegExp=/^1/lete:Error=newError('errormessage')BOM和DOM的内置对象Window、Document、HTMLElement、DocumentFragment、Event、NodeListconstdiv:HTMLElement=document.getElementById('test')constdivs:NodeList=document.querySelectorAll('div')document.addEventListener('click',(event:MouseEvent)=>{console.dir(event.target)})constfragment:DocumentFragment=document.createDocumentFragment()
声明文件在使用第三方库时,第三方库有很多的全局变量,在使用TypeScript时,TypeScript不知道这些全局变量,就会报错,智能提示也不好比如在平常使用jQuery时,直接在<script>标签引入jQuery就会有$或jQuery了,但在TypeScript中就不知道//安装jQuery:npminstalljquery//导入jqueryimport{jQuery}from"jquery";jQuery('#foo')#就会报错就需要使用declarevar定义它的类型declarevar并没有真的定义一个变量,只是定义了全局变量jQuery的类型,仅仅会用于编译时的检查,在编译结果中会被删除。import{jQuery}from"jquery";declarevarjQuery:(selector:string)=>any;jQuery('#foo');手动定义声明文件声明文件名字格式:xxx.d.ts,TS编译器会自动去扫描这类文件创建jQuery.d.ts把下面这句从上面独立出来declarevarjQuery:(selector:string)=>any;缺点:这么多库,这么多全局变量,不可能自己加,所以这些都提供有自己的声明文件下载库自己的声明文件很多的第三方库都定义了对应的声明文件库,库文件名一般为@types/xxx可以在https://www.npmjs.com/package/package进行搜索有的第三库在下载时就会自动下载对应的声明文件库(比如:webpack),有的可能需要单独下载(比如jQuery/react)//下载jQuery声明文件npminstall@types/jquery--save-dev
ORM说明SQLAlchemy是Python中,通过ORM操作数据库的框架。简单点来说,就是帮助我们从烦冗的SQL语句中解脱出来,从而不需要再去写原生的SQL语句,只需要用Python的语法来操作对象,就能被自动映射为SQL语句。安装SQLAlchemy:pip3installSQLAlchemy使用本文以sqlite数据为例,当然sqlalchemy也支持其他数据,MySQL、PostgreSQL、Oracle、MSSQL...连接引擎任何SQLAlchemy应用程序的开始都是一个Engine对象,此对象充当连接到特定数据库的中心源,提供被称为connectionpool的对于这些数据库连接。"""配置连接数据库database.py"""fromsqlalchemyimportcreate_engineDATABASE_URL='sqlite:///orm.db'#sqlite://数据库路径engine=create_engine(#创建引擎DATABASE_URL,encoding='utf-8',echo=True,#引擎将用repr()函数记录所有语句及其参数列表到日志connect_args={'check_same_thread':False},#【使用sqlite数据库才配置】sqlalchemy是多线程的,'check_same_thread':False来让建立的任意线程都可以使用)声明映射Python中的一个类,对应一个表,类的每个属性对应表的字段名。每个映射类都需要继承declarative_base()"""配置连接数据库database.py"""fromsqlalchemy.ormimportdeclarative_baseBase=declarative_base()创建两张表,我们不需要事先在数据库创建表"""ORM操作的模型类models.py"""fromsqlalchemyimportColumn,Integer,String,Enum,DateTime,func,ForeignKeyfromdatabaseimportBase,engineclassClassRoom(Base):__tablename__='orm_classroom'#表名id=Column(Integer,primary_key=True,index=True,autoincrement=True)classroom_num=Column(Integer,unique=True,nullable=False,comment='几班')teacher=Column(String(100),unique=False,nullable=False,comment='班主任')student_num=Column(Integer,unique=False,nullable=False,comment='班级人数')create_at=Column(DateTime,server_default=func.now(),comment='创建时间')update_at=Column(DateTime,server_default=func.now(),onupdate=func.now(),comment='更新时间')def__repr__(self):#方便显示returnf'id={self.id}classroom_num={self.classroom_num}teacher={self.teacher}student_num={self.student_num}'classStudent(Base):__tablename__='orm_student'#表名id=Column(Integer,primary_key=True,index=True,autoincrement=True)#主键自增name=Column(String(100),unique=False,nullable=False,comment='姓名')#字符串不唯一不为空备注sex=Column(Enum('男','女'),comment='性别')classroom_num=Column(Integer,ForeignKey('orm_classroom.classroom_num'),comment='所属班级')create_at=Column(DateTime,server_default=func.now(),comment='创建时间')update_at=Column(DateTime,server_default=func.now(),onupdate=func.now(),comment='更新时间')def__repr__(self):#方便显示returnf'id={self.id}name={self.name}sex={self.sex}classroom_num={self.classroom_num}'Base.metadata.create_all(engine)#创建表运行models.py文件创建会话参数autoflush、autocommit的说明,推荐博客:https://zhuanlan.zhihu.com/p/48994990"""配置连接数据库database.py"""#在SQLAlchemy中,CRUD都是通过会话(session)进行的,所以我们必须要先创建会话SessionLocal=sessionmaker(bind=engine,autoflush=False,#关闭flush()函数的调用,flush()作用是发送语句到数据库,但数据库不一定执行写入磁盘操作autocommit=False,#关闭commit()函数调用,commit()作用是提交事务,将变更保存到数据库文件expire_on_commit=True)进行crud操作封装"""对数据库增删改查crud.py""""""对数据库增删改查crud.py"""fromsqlalchemy.ormimportSessionfromstoragesimportmodels,schemas#增defcreate_student(db:Session,student:schemas.CreateStudent):"""传入BaseMode实例"""db_student=models.Student(**student.dict())db.add(db_student)db.commit()#提交事务db.refresh(db_student)#刷新returndb_student#增defcreate_class_room(db:Session,classroom:schemas.CreateClassRoom):"""传入BaseMode实例"""db_classroom=models.Student(**classroom.dict())db.add(db_classroom)db.commit()#提交事务db.refresh(db_classroom)#刷新returndb_classroom#查defget_student_by_id(db:Session,student_id:int):"""通过id查询学生表"""returndb.query(models.Student).filter(models.Student.id==student_id).first()#查defget_student_by_name(db:Session,name:str):"""通过name查询学生表"""returndb.query(models.Student).filter(models.Student.name==name)#删defdel_student_by_id(db:Session,student_id:int):student=get_student_by_id(db,student_id)db.delete(student)#先查询再删除db.commit()returnstudent#改defupdate_student_name_by_id(db:Session,student_id:int,name:str):student=get_student_by_id(db,student_id)student.name=name#查询结果修改提交事务db.commit()returnstudent使用"""主文件main.py"""fromstorages.databaseimportSessionLocal,Base,enginefromstorages.crudimportcreate_student,get_student_by_id,del_student_by_id,update_student_name_by_idfromstorages.schemasimportCreateStudentBase.metadata.create_all(engine)#创建表db=SessionLocal()student=CreateStudent(name='Bob',sex='男',classroom_num=1)create_student(db=db,student=student)print('查询结果',get_student_by_id(db=db,student_id=1))#print('删除结果',del_student_by_id(db=db,student_id=2))#print('修改结果',update_student_name_by_id(db=db,student_id=3,name='Aoa'))查询数据query()的使用query()可以理解为SQL的selectdb.query(models.Student).filter()过滤db.query(models.Student).filter_by()根据关键字过滤db.query(models.Student).all()返回全部【列表】db.query(models.Student).first()返回第一个元素db.query(models.Student).one()有且只有一个元素时才正确返回db.query(models.Student).one_or_none(),类似one,但如果没有找到结果,则不会引发错误db.query(models.Student).scalar(),调用one方法,并在成功时返回行的第一列db.query(models.Student).count()计数db.query(models.Student).order_by()排序filter()与filter_by()过滤filter()使用#等于db.query(models.Student).filter(Student.name=='Bob')#不等于db.query(models.Student).filter(Student.name!='Bob')#like和ilikedb.query(models.Student).filter(Student.name.like('%Bob%'))db.query(models.Student).filter(Student.name.ilike('%Bob%'))#不区分大小写#isdb.query(models.Student).filter(Student.name==None)#isnotdb.query(models.Student).filter(Student.name!=None)#andfromsqlalchemyimportand_db.query(models.Student).filter(and_(Student.name=='Bob',Student.id==2))db.query(models.Student).filter(Student.name=='Bob',Student.fullname==2)db.query(models.Student).filter(Student.name=='Bob').filter(Student.fullname==2)#orfromsqlalchemyimportor_db.query(models.Student).filter(or_(Student.name=='Bob',Student.name=='Aoa'))#matchdb.query(models.Student).filter(Student.name.match('Bob'))filter_by()使用#id是模型的字段db.query(models.Student).filter_by(id=student_id,name='Bob').first()jion()连接查询db.query(models.Student).join(models.ClassRoom).\filter(\models.Student.classroom_num==models.ClassRoom.classroom_num\).all()
说明泛型的使用:当定义类型时(函数、变量、接口、类),只有在使用的时候,才只是具体是什么类型时,就可以使用泛型定义引入实现生成传入指定元素,指定长度的数组functioncreatArray(value:any,count:number):any[]{letarr:any[]=[];//需要初始化for(leti=0;i<count;i++){arr.push(value);}returnarr;}console.log(creatArray('XX',5))//['XX','XX','XX','XX','XX']使用泛型functioncreatArray<T>(value:T,count:number):T[]{letarr:T[]=[];//需要初始化for(leti=0;i<count;i++){arr.push(value);}returnarr;}console.log(creatArray<number>(22,5))//[22,22,22,22,22]多个泛型参数的函数泛型常用字母K、V、TfunctioncreatArray<K,V>(x:K,y:V):[K,V]{return[x,y]}console.log(creatArray<number,string>(22,'XX'))//[22,'XX']泛型接口在实现接口时,再定义类型//泛型接口interfaceIbaseCRUD<T>{data:T[]add(t:T):voidgetById(id:number):T}classUser{id?:number;//id主键name:string;age:number;constructor(name:string,age:number){this.name=name;this.age=age;}}classUserCRUDimplementsIbaseCRUD<User>{data:User[]=[]add(user:User):void{user={...user,id:Date.now()}this.data.push(user);console.log('saveuser',user)}getById(id:number):User{returnthis.data[id]}}constuserCRUD=newUserCRUD()userCRUD.add(newUser('XX',16))userCRUD.add(newUser('YY',17))console.log(userCRUD.getById(1))//{name:'YY',age:17,id:1646630710525}泛型类在实例化类时,再定义类型classUser{name:string;age:number;constructor(name:string,age:number){this.name=name;this.age=age;}}classUserCRUD<T>{data:T[]=[]add(user:T):void{this.data.push(user);console.log('saveuser',user)}}constuserCRUD=newUserCRUD<User>();userCRUD.add(newUser('XX',16))//saveuserUser{name:'XX',age:16}泛型约束当使用泛型时,函数逻辑中,可能并不知道该类型有这个方法或属性,而报错,智能提示也不好functionfn<T>(x:T):void{//console.log(x.lenght)//报错:类型“T”上不存在属性“lenght”。}处理:泛型继承某类、某接口一个泛型变量只能继承一个类或者接口classUser{constructor(publicname:string,publicage:number){}}//泛型继承User类functionfn<TextendsUser>(x:T):void{console.log(x.name,x.age)}//传入符合这中类型的值fn(newUser('XX',16))//XX16
函数函数的参数和返回值是可以定义的类型的//命名函数functionfun(x:number,y:number):number{returnx+y;}//匿名函数letlo=function(msg:string):void{//viod表示没有返回值console.log('匿名函数')}可选参数&默认参数可选参数?关键字functionadd(x:number,y:number,flag?:boolean):number{if(flag){returnx+y;}else{returnx-y;}}console.log(add(5,3,true));//8console.log(add(5,3));//2默认参数functionadd(x:number,y:number=3,flag?:boolean):number{if(flag){returnx+y;}else{returnx-y;}}console.log(add(5,3));//2console.log(add(5));//2剩余参数在Python、Java里叫不定长参数functionadd(x:number,...args:number[]):number{console.log(x,args)//5[4,3,2,1]args.forEach(num=>{x+=num;});returnx;}console.log(add(5,4,3,2,1));//15函数重载Java的重载,是函数名一样,参数列表不一样,而TypeScript有点不一样函数参数定义有类型断言,声明重载,规范传入参数的类型//重载函数声明。相对于规范传入参数的类型functionadd(x:string,y:string):string;functionadd(x:number,y:number):number;functionadd(x:number|string,y:number|string):number|string{if(typeofx==="number"&&typeofy==="number"){returnx+y;//数字类型相加}if(typeofx==="string"&&typeofy==="string"){returnx+'+'+y;//字符串拼接}}console.log(add('**','**'))//**+**console.log(add(3,5))//8
说明对于传统的JavaScript程序我们会使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员使用这些语法就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的。从ECMAScript2015,也就是ES6开始,JavaScript程序员将能够使用基于类的面向对象的方式。使用TypeScript,我们允许开发者现在就使用这些特性,并且编译后的JavaScript可以在所有主流浏览器和平台上运行,而不需要等到下个JavaScript版本。类的结构类的主要元素:属性、构造器、方法classCat{//属性name:stringage:number//构造函数constructor(name:string,age:number){this.name=name;this.age=age;}//普通方法eat():void{console.log(`${this.name}吃玉米`)}}letcat:Cat=newCat('O_O',12);cat.eat()继承&多态关键字extendsclassAnimal{//属性name:stringage:numberconstructor(name:string,age:number){this.name=name;this.age=age;}run(distance:number):void{console.log(`Animalrun${distance}m`)}}classCatextendsAnimal{//继承type:string//构造函数constructor(name:string,age:number){super(name,age)//调用父类构造函数}//普通方法eat():void{console.log(`${this.name}吃玉米`)}//重写父类方法run(distance:number):void{console.log(`${this.name}run${distance}m`)}}letcat:Cat=newCat('O_O',12);cat.run(15)权限修饰符默认公共public,实例对象,类内部,子类都可以访问私有private,只有类内部可以访问保护protected,类内部、子类之类可以访问classAnimal{//属性protectedname:string//当前类内部子类publicage:number//公共constructor(name:string,age:number){this.name=name;this.age=age;}run(distance:number):void{console.log(`Animalrun${distance}m`)}}classCatextendsAnimal{//继承privatetype:string//当前类内部//构造函数constructor(name:string,age:number){super(name,age)//调用父类构造函数}//普通方法eat():void{console.log(`${this.name}吃玉米`)}//重写父类方法run(distance:number):void{console.log(`${this.name}run${distance}m`)}}letcat:Cat=newCat('O_O',12);cat.run(15)console.log(cat.age)//12readonly修饰符readonly修饰属性为可读,只能在定义时或者构造函数初始化classPerson{readonlyname:string='abc'constructor(name:string){this.name=name}}letjohn=newPerson('John')参数属性TypeScript不一样的地方,作用简化代码不止能写readonly,其他权限public,private,protected//与上一个代码效果一样classPerson{constructor(readonlyname:string){}}letjohn=newPerson('John')静态属性不用实例化就能获取的属性classDog{staticname_:string='O_O'}console.log(Dog.name_)//'O_O'抽象类抽象类和抽象方法用abstract关键字抽象类作为其它类继承使用。抽象类不能被实例化。不同于接口,抽象类的普通方法可以有方法体,但抽象方法不能有方法体抽象方法必须在抽象类里abstractclassAnimal{abstracteat():void;//抽象方法没有实现细节run(x:number){//继承后普通方法可以不用实现console.log(`xxrun${x}m`)}}classDogextendsAnimal{eat(){//必须实现全部抽象方法的方法体console.log(`dogeatxx`)}}letdog:Dog=newDog()dog.run(15)//xxrun15m
接口说明接口是对象的状态(属性)和行为(方法)的抽象(描述),简单理解就是规范结构,接口不能初始化属性TypeScript的核心原则之一是对值所具有的结构进行类型检查。我们使用接口(Interfaces)来定义对象的类型。接口结构结构关键字interfaceinterfaceIPersion{id:numbername:stringage:string}constperson:IPersion={id:1,name:'o_o',age:14};可选属性interfaceIPersion{id:numbername:stringage?:string//该属性可以不存在}constperson:IPersion={id:1,name:'o_o'};只读属性关键字readonly该值只能在初始化时被改变,除此之外不能被改变interfaceIPersion{id:numberreadonlyname:string//只读age?:number}letperson:IPersion={id:1,name:'o_o'};person.id=2;//person.name='*_*';//报错不呢被改变readonlyvsconstreadonly修饰属性const修饰变量接口规范函数类型看着可能有点奇怪,这里明确一个概念,函数的必要元素:参数列表、返回值。(匿名没有函数名,所以函数名非必要)//定义函数类型interfaceIFunType{//参数列表:返回值(s1:string,s2:string):string}//变量类型为函数letfun:IFunType=function(s1:string,s2:string):string{return`${s1}_${s2}`}console.log(fun('kk','xx'));类接口作用于Java、C#里面一样,类需要实现接口interfaceIAnimal{type:stringeat():void}classCatimplementsIAnimal{type:string='猫'eat(){console.log(`${this.type}吃${this.type}粮`)}}letcat:Cat=newCat();cat.eat()接口继承接口接口间叫继承interfaceIAnimal{//动物接口type:stringeat():void}interfaceIFelidaeextendsIAnimal{//猫科接口继承动物接口leg_num:number}类实现多个接口interfaceIAnimal{//动物接口type:stringeat():void}interfaceIPerson{name:stringage:number}classPersonimplementsIAnimal,IPerson{type:string='person'name:stringage:numbereat(){console.log(`${this.type}吃玉米`)}}letperson:Person=newPerson();person.eat()//person吃玉米
说明TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型布尔值letmsg:boolean=true;数字TypeScript里的所有数字都是浮点数。这些浮点数的类型是number。letn1:number=12;//十进制letn2:number=0b1010;//二进制letn3:number=0o12;//八进制letn4:number=0xa;//十六进制字符串单引号双引号都可以lets:string='xxx';undefined和null它们的本身的类型用处不是很大letund:undefined=undefined;letnu:null=null;数组TypeScript像JavaScript一样可以操作数组元素。有两种方式可以定义数组。第一种,let变量名:类型[]=[];letarr:number[]=[1,2,3,4];第二种泛型定义,Array<类型>letarr:Array<number>=[1,2,3,4];元组元组类型允许表示一个已知元素数量和类型的数组lettu:[number,string,boolean]=[1,'咪咪',true];枚举enum类型是对JavaScript标准数据类型的一个补充enumColor{Red,//0Green=10,Blue//11}letcolor:Color=Color.Blue;console.log(Color)//0any当不知定义什么类型比较合适时使用leta:any;a=12;a='12';letb:any=12;b='a';console.log(a,b)//'12''a'object所有对象的基类leto:object={'a':12};letoo:object=newString('oo');联合类型表示取值为多种类型中的一种functionfun(s:number|string):number|string{returns}类型断言当使用联合类型时,编译器可能不知道,现在我们处理的时候什么类型,而出现报错,因此就需要告诉编译现在处理的是什么。/*两种定义方式:第一种:(<类型>变量)第二种:(变量as类型)*/functionfun(s:number|string):number{//返回参数的长度if((<string>s).length){return(<string>s).length;}else{return(sasnumber).toString().length;}}类型推断当不定义类型是,TypeScript会自动推断类型,如果只是定义,不初始化变量,则类型为anyletn=123;//推断类型为number//n='a';//报错letm;//推断类型为anym=12;m='a';