安装TypeScript环境
搞点前端框架基础,整个全栈的饭碗吃吃
在项目中安装TypeScript
进入项目目录下安装
npm install typescript --save-dev
D:\anglarProject\gavin>npm install typescript --save-dev removed 1 package, and audited 917 packages in 1m 122 packages are looking for funding run `npm fund` for details found 0 vulnerabilities
复制
也可以在 全局中安装
npm install -g typescript
如果下载typescript时速度过慢,可以考虑换一个镜像源~国内镜像源
npm config set registry https://registry.npmmirror.com
TypeScript是js的超级集
开始一个新的项目来学习TypeScript的使用:
typescript的常用编译命令
首先学习一下typescript的语法:
我们要明确一点ts是js的超级,即ts是兼容js的,ts相对于js增加了一些功能:
类型批注和编译时类型检查 类型推断 类型擦除 接口 枚举 Mixin 泛型编程 名字空间 元组 Await 以下功能是从 ECMA 2015 反向移植而来: 类 模块 lambda 函数的箭头语法 可选参数以及默认参数
复制
先来打印一下helloworld:
新建一个hello.ts文件,里面的内容如下:
const hello:string="hello_world" console.log(hello)
复制
用typescript来编译一下:
tsc hello.ts
用node来运行一下刚刚编译生成的js文件
D:\anglarProject>node hello.js Hello World!
复制
下面随便整一个html文件,引入hello.js
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>TypeScript学起来</title> <script src="hello.js"></script> </head> <body> <div>前路白云外,孤帆安可论</div> </body> </html>
复制
我们可以同时编译多个ts文件(文件之间用空格隔开就好了)
tsc 常用的编译参数:
直接编译ts文件:
tsc 文件名.ts —>>会生成一个同名的js文件
将声明的变量给提取出来
tsc --declaration hello.ts
编译时会生成一个.d.ts文件
.d.ts文件的内容
为了编译时更加简洁,可以在编译时将注释给过滤掉
tsc --removeComments hello.ts
const hello : string = "Hello World!" console.log(hello) //这是注释文件 alert("hello") var hi="你好世界" alert(hi)
复制
编译一下:
tsc --declaration --removeComments hello.ts
打开index文件可以体验一下
多个文件合并输出到一个文件
tsc hello.ts hi.ts --out hello.js
新建一个.ts文件,
function displayDate(){ document.getElementById("demo").innerHTML=Date(); }
复制
index.html文件内容如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>TypeScript学起来</title> <script src="hello.js"></script> </head> <body> <div>前路白云外,孤帆安可论</div> <p id="demo">点击按钮显示日期</p> <button type="button" onclick="displayDate()">显示日期</button> </body> </html>
复制
源代码存储以及代码对于每个位置映射关系的信息.map的文件:
.map的文件内容
有版本号,文件名,来源 映射关系—>>这映射关系四个字母一组,具体映射关系暂不去管他了
{"version":3,"file":"hello.js","sourceRoot":"","sources":["hello.ts","hi.ts"],"names":[],"mappings":"AAAA,IAAM,KAAK,GAAY,cAAc,CAAA;AACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAClB,QAAQ;AACR,KAAK,CAAC,OAAO,CAAC,CAAA;AAEd,IAAI,EAAE,GAAC,MAAM,CAAA;AAEb,KAAK,CAAC,EAAE,CAAC,CAAA;ACPT,SAAS,WAAW;IACnB,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,SAAS,GAAC,IAAI,EAAE,CAAC;AAClD,CAAC"}
复制
监视ts文件,在他们改变时重新编译
tsc --watch
tsc hello.ts hi.ts --declaration --sourcemap --removeComments --out hello.js --watch
注意:watch要放在最后
typescript的一些特点
1,typejs会忽略程序中的空格,制表符,换行符
2,typejs区分大小写
3,结束符分号是可选的,(如果语句写在一行上,是需要分隔符的)
typejs中的注释
单行注释 //
多行注释/* */
在编译时可以忽略掉注释
tsc --removeComments
TypeJs面向对象的戏码
这个就很java了
对象,类,方法…
整呗~~新建一个ts文件,
//这是一个类 class hello{ //这是一个变量 name ="我是一个粉刷匠" //这是一个构造方法 constructor ( ){ } //这是一个方法 printName():string{ return this.name } } //实例化 var obj=new hello(); //打印 console.log(obj.printName());
复制
运行生成的js文件
D:\anglarProject>node ty.js 我是一个粉刷匠
复制
编译之后生成的js文件:
//这是一个类 var hello = /** @class */ (function () { //这是一个构造方法 function hello() { //这是一个变量 this.name = "我是一个粉刷匠"; } //这是一个方法 hello.prototype.printName = function () { return this.name; }; return hello; }()); //实例化 var obj = new hello(); //打印 console.log(obj.printName());
复制
看起来ts文件确实要比js好写一些
TS基础数据类型:
any —>>任意类型
任意值类型可以让这些变量跳过编译阶段的类型检查
let yyds:any =1 console.log(yyds) yyds ="我就是一个string类型" console.log(yyds) yyds=true console.log(yyds) let ds:string="long ranger" ds="我只能是字符串了" console.log(ds)
复制
生成的js文件:
//类型推断 var yyds = 1; console.log(yyds); yyds = "我就是一个string类型"; console.log(yyds); yyds = true; console.log(yyds); var ds = "long ranger"; ds = "我只能是字符串了"; console.log(ds);
复制
let x: any = 4; x.ifItExists(); // 正确,ifItExists方法在运行时可能存在,但这里并不会检查 x.toFixed(); // 正确
复制
number–>>数字类型 可以表示整数和小数
string -->>字符串
单引号和双引号都可以,
注意:使用反引号时可以定义多行文本和内嵌表达式
boolean -->>布尔类型
var name1 = "Hello"; var years = 5; var words words = `您好,我是 ${ name1 } 年纪 ${ years + 1} `; console.log(words)
复制
编译后生成的js文件:
var name1 = "Hello"; var years = 5; var words; words = "\u60A8\u597D\uFF0C\u6211\u662F ".concat(name1, " \u5E74\u7EAA ").concat(years + 1, " "); console.log(words);
复制
在新版本的typejs中,有一个关键字 let
var name1 = "Hello"; var years = 5; var words words = `您好,我是 ${ name1 } 年纪 ${ years + 1} `; console.log(words) let helo:string ="haha" //数字类型 let size:number=100 //反引号 let result:string =`这就是个测试 ${helo} 数字是${size}` //布尔类型 let bool:boolean=true console.log(bool) console.log(result)
复制
编译后生成的js
var name1 = "Hello"; var years = 5; var words; words = "\u60A8\u597D\uFF0C\u6211\u662F ".concat(name1, " \u5E74\u7EAA ").concat(years + 1, " "); console.log(words); var helo = "haha"; //数字类型 var size = 100; //反引号 var result = "\u8FD9\u5C31\u662F\u4E2A\u6D4B\u8BD5 ".concat(helo, " \u6570\u5B57\u662F").concat(size); //布尔类型 var bool = true; console.log(bool); console.log(result);
复制
数组类型,元组,枚举
let arr:number[]=[1,2,3,4,5]; console.log(arr) //泛型数组 class Person{ public name:string public age:number constructor ( name:string, age:number){ this.name=name this.age=age } } let arr2:Array<Person>=[new Person("Sofia",26),new Person("Halo",28)] console.log(arr2) //元组 元素顺序对应的数据类型要一致 let xx:[string,number,boolean] xx=["hello",100,true] console.log(xx) console.log(xx[0]) //枚举 enum Color{red,green,blue}; let r:Color=Color.red console.log(r)//打印数字 //方法 function printData():void{ console.log("随便玩一下") } function printD(name:string):string{ return name } console.log(printD("amazing"))
复制
编译后运行:—>>
生成的js文件:
var arr = [1, 2, 3, 4, 5]; console.log(arr); //泛型数组 var Person = /** @class */ (function () { function Person(name, age) { this.name = name; this.age = age; } return Person; }()); var arr2 = [new Person("Sofia", 26), new Person("Halo", 28)]; console.log(arr2); //元组 元素顺序对应的数据类型要一致 var xx; xx = ["hello", 100, true]; console.log(xx); console.log(xx[0]); //枚举 var Color; (function (Color) { Color[Color["red"] = 0] = "red"; Color[Color["green"] = 1] = "green"; Color[Color["blue"] = 2] = "blue"; })(Color || (Color = {})); ; var r = Color.red; console.log(r); //打印数字 //方法 function printData() { console.log("随便玩一下"); } function printD(name) { return name; } console.log(printD("amazing"));
复制
现在有点体会到了,ts语言的定义方式某些程度上更倾向于java的风格
**null **
表示对象值缺失。
在js中null也是一种是数据类型,表示一个空对象
我们用type来检测null时,返回的是个object
console.log(typeof(null)) console.log(typeof(typeof(null)))
复制
编译后:
console.log(typeof(null)) console.log(typeof(typeof(null))) let size:number size=10 size=undefined size=null console.log(size) //null
复制
undefined
用于初始化变量为一个未定义的值
console.log(typeof(null)) console.log(typeof(typeof(null))) let size:number size=10 size=null size=undefined console.log(size) //undefined
复制
never
never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。
let yyds:never let num:number //yyds=100 编译不通过,数字不能转never类型 num=(()=>{throw new Error("抛个异常")})(); yyds=(()=>{throw new Error("never类型可以赋值给数字类型")})(); function err(msg:string):never{ throw new Error("抛个异常") } function deadloop():never{ while(true){ } }
复制
js文件
var yyds; var num; //yyds=100 编译不通过,数字不能转never类型 num = (function () { throw new Error("抛个异常"); })(); yyds = (function () { throw new Error("never类型可以赋值给数字类型"); })(); function err(msg) { throw new Error("抛个异常"); } function deadloop() { while (true) { } }
复制
JavaScript let 和 const
JavaScript let 和 const
ECMAScript 2015(ECMAScript 6)
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
在 ES6 之前,JavaScript 只有两种作用域: 全局变量 与 函数内的局部变量。
简单来说 使用var 声明的变量 相当于全局的变量,在代码块中修改 该变量会影响该值
如果是用let声明,那么该变量只在所在代码块中起作用;
TypeScript中的变量声明
//变量的声明 var names : string ="小明" console.log(names) var age : number console.log(age)//因为变量没有初始值此时值为undifined //带类型推断的 var color="RED" enum Colors{red,green,blue}; var c=Colors.red console.log(c)
复制
TypeScript 遵循强类型,如果将不同的类型赋值给变量会编译错误,
var num:number = “hello” // 这个代码会编译错误
类型断言:
类型断言可以用来手动指定一个值得类型,即允许变量从一种类型更改为另一种类型,
//变量的声明 var names : string ="小明" console.log(names) var age : number console.log(age)//因为变量没有初始值此时值为undifined //带类型推断的 var color="RED" console.log(typeof(color)) enum Colors{red,green,blue}; var c=Colors.red console.log(c) //这里声明一个字符串数字, var str ='100' //通过断言来转换为数字类型,但是底层依旧是 var str2:number=<number> <any> str console.log(str2) console.log(typeof(str2))//这里类型依旧是string let num:number =100 console.log(typeof(num))
复制
编译后运行
这里可以发现断言之后的数据类型并没有转换成number类型, 是因为转换通常意味着某种运行时的支持,java中可以通过
String.valueOf()
Integer.valueOf() 来进行类型转换
类型推断
var name;//声明时没有赋值,没有确定数据类型 name="string" //这里类型推断 name=100//这里报错,因为第二行已经能够确定数据的类型了
复制
变量作用域
var name2;//声明时没有赋值,没有确定数据类型 name2="string" //这里类型推断 //name2=2100//这里报错,因为第二行已经能够确定数据的类型了 var global_num=12 class Demo{ num =13; static size=10; storeNum():void { var local_num=14 } } console.log("全局变量为: "+global_num) console.log(Demo.size) // 静态变量 var obj = new Demo(); console.log("实例变量: "+obj.num)
复制
编译后 运行
TypeScript中的运算符
说一下负号运算符:
var num12=100 var y= -num12 console.log(num12) console.log(y)
复制
TypeScript中的循环
var num =1 for(;num<=10;num++){ console.log(num) } var arr =[1,2,3,4,5,6,7,8,9] for (let index = 0; index < arr.length; index++) { const element = arr[index]; if (element==6){ break;//跳出循环 } console.log(element); }
复制
TypeScript中的函数
带参数的函数:
function add(x :number,y:number):number{ return x+y } console.log(add(10,100))
复制
可选参数:
参数名后用?表示该参数可选
function add(x :number,y:number):number{ return x+y } console.log(add(10,100)) function printData(x:string ,y:number,z?:string){ console.log(x,y,z) } printData("你好",12) printData("hello",19,"world")
复制
参数默认值
function add(x :number,y:number):number{ return x+y } console.log(add(10,100)) function printData(x:string ,y:number,z:string="世界"){ console.log(x,y,z) } printData("你好",19) printData("hello",20,"world")
复制
当我们第三个参数不传时,会使用默认值
定义方式为: 参数名:类型 =value
可选参数必须跟在必需参数后面。
参数不能同时设置为可选和默认。
PS D:\anglarProject> node .\fun.js 110 你好 19 世界 hello 20 world
复制
可变参数:
function selection(str:string,...m:string[]){ console.log(str,m) } selection("hello","world","你好","北京欢迎你") function sprint(...str:any[]){ console.log(str) } sprint("他不懂你的心","骑自行车的风景")
复制
编译后运行:
hello [ 'world', '你好', '北京欢迎你' ] [ '他不懂你的心', '骑自行车的风景' ]
复制
TypeScript匿名函数
匿名函数自调用
//匿名函数 var func=function(str:string):string{ return str } console.log(func("匿名函数")); (function():void{ var str="hellohahaha" console.log(str) })();//函数自调用 //带有参数的函数自调用 (function (str:string):string{ console.log(str) return str })("hello");
复制
编译后生成的js文件:
//匿名函数 var func = function (str) { return str; }; console.log(func("匿名函数")); (function () { var str = "hellohahaha"; console.log(str); })(); //函数自调用 //带有参数的函数自调用 (function (str) { console.log(str); return str; })("hello");
复制
TypeScript构造函数
class Person{ name :string hobby :string constructor(name:string,hobby:string){ this.name=name this.hobby=hobby } } var per =new Person("张三","跑步") console.log(per) class MathAdd{ constructor(a:number,b:number){ } } //Function是一个接口 直接new一个该接口,传入 string[]类型的参数 然后定义返回值 var myFunction = new Function("a", "b", "return a * b"); var x = myFunction(4, 3); console.log(x); // var obj=new MathAdd("a","b","return a + b"); var test = new Function("a","b","return a + b") console.log(test(10,12)) // 递归调用 function factorial(number) { if (number <= 0) { // 停止执行 return 1; } else { return (number * factorial(number - 1)); // 调用自身 } } ; console.log(factorial(6)); // 输出 720
复制
TypeScript中lambda表达式
// lambda函数 var fool =(s:number)=>100+x console.log(fool) console.log(fool(19)) var dtse=y=>{ // 参数类型让他自己去推断,或者给指定好 console.log(y) } var dtse2=y=>{ // 参数类型让他自己去推断,或者给指定好 if (typeof y =="string"){ console.log(y) }else{ console.log("啥也不是") } } dtse("大江大河") dtse2("hell")
复制
无参数时可以设置空括号:
var disp =()=> { console.log("Function invoked"); } disp();
复制
TypeScript中函数重载
这个跟java中函数的重载逻辑是一样的
//函数重载 function disp(s1:string):void; function disp(n1:number,s1:string):void; function disp(x:any,y?:any):void { console.log(x); console.log(y); } disp("abc") disp(1,"xyz") //定义一个方法 隐式的返回any function add(a:number):any; function add(a:number,b:string):void; // 定义一个方法 function add(a:string,b:string,c:number):void; // 实现 方法以便实现方法的重载 /** * 如果参数类型不同,则参数类型应设置为 any。 * 参数数量不同你可以将不同的参数设置为可选。 * * @param a * @param b */ function add(a:any,b:string,c?:number):void{ }
复制
函数重载:
1,如果参数类型不同,则参数类型应设置为 any。
2,参数数量不同你可以将不同的参数设置为可选。
Number对象
// NUmber中的函数 var size= new Number(100.789) var niubi=size.toExponential();//把对象的值转换为指数计数法 console.log(niubi) console.log(typeof(size.toFixed()))//string console.log(size.toFixed(2)) //保留小数点后2位 console.log(size.toLocaleString)//当地的数字格式顺序 console.log(typeof(size.toPrecision())) console.log(size.toPrecision(2))//把数字格式化指定长度 console.log(size.toPrecision(4)) console.log(size.toString(10))// console.log(size.toString(2))//数字转换位字符串,可以指定进制 console.log(size.valueOf())//
复制
String对象
//String var st= new String("嘿嘿"); console.log(st.constructor) console.log(st.length) function employ(id:string){ } var e= new employ("Hello") // employ.prototype.email="添加了属性email" console.log(e.email) console.log(st.charAt(2))//指定位置的字符 console.log(st.charCodeAt(2))//指定位置的字符 Unicode 编码。 console.log(st.concat("拼接字符串")) st.match(/el/o) //匹配 查找找到一个或多个正则表达式的匹配。 st.replace("o","a")//替换 st.search("o")//查找 st.split("o")//分割 st.trim() console.log(st.toLocaleLowerCase()) st.valueof() //其他函数略
复制
Array对象
//数组 var j; var nums = [1001, 1002, 1003, 1004]; for (j in nums) { console.log(nums[j]); } var arr = new Array(1,2,3,4) var str =arr.join() var str2 =arr.join("-") console.log(str) console.log(str2) //遍历 arr.forEach(function (value){ console.log(value) }) var arr1= new Array(5,6,7,8) var newarr =arr.concat(arr1)//数组整合到一个数组中 newarr.forEach(function(value){ console.log(value) }) /* 确定数组的所有成员是否满足指定的测试。 * @param predicate最多接受三个参数的函数。每个方法调用 *数组中每个元素的谓词函数,直到谓词返回一个值 *,它是布尔值false的强制值,或者直到数组结束。 * @param thisArg this关键字可以在谓词函数中引用的对象。 *如果省略thisArg,则使用undefined作为this值。 */ function dayu5(ele ,_index,_array){ return (ele>=5) } // every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean; console.log(newarr.every(dayu5)) // 过滤 function filterRes(ele ,index,array){ return (ele>=4) } console.log(newarr.filter(filterRes)) newarr.indexOf(7)//7的位置 //返回处理之后的数组 var narr=newarr.map(Math.sqrt)//通过指定函数处理数组的每个元素,并返回处理后的数组。 narr.forEach(function(value){ console.log(value) }) // 向数组中添加元素 narr.push(100,200) narr.pop()//从尾部移除,并返回该元素 arr.shift()//删除并返回数组的第一个元素。 arr.unshift(100,300)//像数组添加元素--一个,多个 narr.forEach(function(value){ console.log(value) }) //将数组中元素按规则处理为一个值将 (从左到右) var arrs=arr.reduce(function(a,b){ return a+b }) //(从you到zuo) var arrs=arr.reduceRight(function(a,b){ return a+b }) console.log("arrs--"+ arrs) arr.reverse()//反转数组 // 将数组--切除一块作为新数组 arr.slice(0,4) arr.some(dayu5)//这个跟every()类似 arr.sort() arr.splice(1,2)//从数组位置1开始删除两个元素
复制