简介:TypeScript是一种由微软开发的支持ES6标准的编程语言,它是Angular2的开发语言。它可以编译成纯JavaScript,可以在任何浏览器,任何计算机和任何操作系统上运行,并且是开源的。本课程介绍了TypeScript的基本概念、常用语法和高级特性。
对本课程的大纲进行介绍
课程内容介绍
前置知识
可以理解为
JavaScript实现了ES5,TypeScript实现了ES6
了解学习TypeScript有哪些好处
教你如何使用compiler
什么是compiler?为什么需要compiler?
进入TypeScript官网,打开Playground,可以使用在线compiler开发
在线编译器:https://www.typescriptlang.org/play/index.html
npm --version // 或者npm -v
npm install -g typescript // 全局安装typescript
tsc --version // 查看typescript版本
touch Hello.ts // 创建typescript文件
// Hello.ts 文件内容
export class Hello{
}
tsc Hello.ts // 编译文件 多出一个文件Hello.js
npx tsc Hello.ts // 若安装了nvm,可使用npx
// 编译后Hello.js文件内容
"use strict";
var Hello = (function () {
function Hello() {
}
return Hello;
}());
exports.Hello = Hello;
安装TypeScript编译器,WebStorm IDE有语法提示,可自动编译
1、Create New Project 选择 ts
2、Project->New->Stylesheet->Hello.ts
3、内容写
export class Hello{
}
4、设置里,TypeScript->Compiler->Enable TypeScript Compiler 自动编译
介绍TypeScript中的字符串
1、多行字符串
传统JavaScript字符串换行需要+进行拼接
TypeScript不需要+拼接,而使用双撇号``包起来的模板字符串就可以直接换行,而不报错,被翻译成javascript时会加上换行符
看下面实例:
JavaScript:
var content = "aaa"+
"bbbb";
TypeScript:
var content = `aaa
bbb`;
2、字符串模板
字符串模板就是在多行字符串里用一个表达式插入变量或者调用方法。
普通字符串,变量等不会被解析。
提高开发速度和可读性
var myName = "zhang san";
var getName = function () {
return "zhang san";
}
//调用变量
console.log(`hello ${myName}`);
//插入标签(这样看起来比JavaScript好多了)
console.log(
`
${myName}
${getName}
`
)
//调用方法
console.log(`hello ${getName}`);
console.log(`hello ${getName()}`);
使用字符串模版去拼接一串dom结构的时候无论是从易用性还是可读性方面都比右侧强的多。
3、自动拆分字符串
用字符串模板去调用方法时字符串模板中表达式的值会自动赋值给被调用方法中的参数。
可以看到template中传入的参数是被切割好的3个字符串。
function test (template,name,age) {
console.log(template);
console.log(name);
console.log(age);
}
var myName = "zhang san";
var getAge = function () {
return 18;
}
test `hello my name is ${myName},i 'm ${getAge()}`;
(这里name 就是 ${myName}, age 就是${getAge()})
输入结果:
介绍TypeScript中的参数
在参数名称后面使用冒号来指定参数的类型(变量或方法的参数)
1.当赋值时不是指定类型数值时会报错。
var myname: string = "zhang san";
2.当你没有指定类型时,会默认你第一次赋值的数据类型为当前变量的数据类型,在TypeScript中称为(类型推断机制)
var myname = "zhang san";
myname = 13;//(这时候就会报错)
3.any 类型,当定义为any 类型时,可以赋多种类型的数值。
var myname :any = "zhang san";
myname = 13; //(这样也是正确的)
4、常见参数类型
var myname: string= ""; //字符串类型
var age: number = 13; //number类型
var man: boolean = true; //布尔类型
function test(name: string): void { //无返回值类型.,同时还可以给方法的参数声明类型
}
5.自定义类型,也就是自定义类
class Person {
name: string;
age: number;
}
var zhangsan: Person = new Person();
zhangsan.name = "zhangsan";
zhangsan.age = 18;
IDE有语法提示和自动完成
默认参数:在参数声明后面用等号来指定参数的默认值
1.定义的时候指定默认的参数值
var myname: string = "zhang san";
2.定义函数的时候指定默认的参数值,调用时也必须传入参数才能调用。
function test(a: string, b: string,c:string) {
console.log(a);
console.log(b);
console.log(c);
}
test("xxx","yyy","zzz");//传入的参数也必须是制定的类型才行;
3.带默认值的参数放在最右边,否则报错
function test(a: string, b: string,c:string = "jojo") {
console.log(a);
console.log(b);
console.log(c);
}
test("xxx","yyy","zzz");
test("xxx","yyy");
可选参数:在方法的参数声明后面用问号来标明次参数为可选参数
function test(a: string, b?: string,c:string = "jojo") {
console.log(a);
console.log(b); // console.log(b.length); //不传b则报错
console.log(c);
}
test("xxx","yyy","zzz");
test("xxx","yyy");
test("xxx");
介绍TypeScript中的函数
Rest and Spread操作符: 用来声明任意数量的方法参数(...)
function func1(...args){
args.forEach(function (arg){
console.log(arg);
})
}
func1(1,2,3);
func1(7,8,9,10,11);
根据定义的参数取传入的参数,TypeScript不支持,对应的JS支持
function func1(a, b, c){
console.log(a);
console.log(b);
console.log(c);
}
var args = [1, 2];
func1(...args); // 输出 1 2
var args2 = [7, 8, 9, 10, 11];
func1(...args2);// 输出7 8 9
generator函数:控制函数的执行过程,手工暂停和恢复代码执行
ES5:没法暂停函数
ES6:yield函数打了一个断点一样,.next()执行到yield的地方停下来
babel在线编辑器:https://www.babeljs.cn/repl
function* doSomething () {
console.log("start");
yield;
console.log("finish");
}
//调用generator函数,必须赋值给一个变量
var func1 = doSomething();
//通过next()来调用
func1.next();
func1.next();
function* getStockPrice(stock){
while(true){
yield Math.random()*100;
}
}
var priceGenerator = getStockPrice("IBM");
var limitPrice = 15;
var price = 100;
while(price>limitPrice){
price = priceGenerator.next().value;
console.log(`the generator return ${price}`);
}
console.log(`buying at ${price}`);
destructuring析构表达式:通过表达式将对象或数组拆解成任意数量的变量
// example1
function getStock(){
return {
code: "IBM",
price: 100
}
}
var stock = getStock();
var code = stock.code;
var price = stock.price;
// 从数组中取值变量名相同
// 好处:对象的属性或者数组中元素可以去初始化变量
var {code,price} = getStock();
console.log(code);
console.log(price);
// 变量名不一致,报错
var {codex,price} = getStock();
console.log(codex);
console.log(price);
// 取别名
var {code: codex,price} = getStock();
console.log(codex);
console.log(price);
// example2
function getStock(){
return {
code: "IBM",
price: {
price1: 200,
price2:400
}
}
}
var {code,price} = getStock();
console.log(code);
console.log(price); // price 是一个对象
var {code,price:{price2}} = getStock();
console.log(code);
console.log(price2); // 输出400
// example3
function getStock(){
return {
code: "IBM",
price: {
price1: 200,
price2:400
},
aaa: "xixi",
bbb: "haha"
}
}
var {code:codex,price:{price2}} = getStock();
console.log(codex);
console.log(price2);
// example4
var array1 = [1,2,3,4];
var [number1,number2]= array1;
console.log(number1); // 1
console.log(number2); // 2
// example5
var array1 = [1,2,3,4];
var [,,number1,number2]= array1;
console.log(number1); // 3
console.log(number2); // 4
// example6
var array1 = [1,2,3,4];
var [number1,,,number2]= array1;
console.log(number1); // 1
console.log(number2); // 4
// example7
var array1 = [1,2,3,4];
var [number1,number2,...others]= array1;
console.log(number1); // 1
console.log(number2); // 2
console.log(others); // [3,4]
// example8
var array1 = [1,2,3,4];
var [number1,number2,...others]= array1;
function doSomething(number1,number2,...others){
console.log(number1); // 1
console.log(number2); // 2
console.log(others); // [3,4]
}
doSomething(array1);
介绍TypeScript中的箭头表达式和for of循环
箭头表达式:用来声明匿名函数,消除传统匿名函数的this指针问题
// example1
var sum = (arg1, arg2) => arg1 + arg2; // 不换行可省略{}
var sum = (arg1, arg2) => (
return arg1 + arg2;
)
var sum = arg1 => {
console.log(arg1);
}
// example2
var myArray = [1,2,3,4,5];
console.log(myArray.filter(value => value%2==0)); // [2,4]
// example3
function getStock(name: string){
this.name = name;
setInterval(function(){
console.log("name is : "+ this.name);
},1000);
}
var stock = getStock("IBM"); // name is :
function getStock2(name: string){
this.name = name;
setInterval(() => {
console.log("name is : "+ this.name);
},1000);
}
var stock = getStock2("IBM"); // name is : IBM
forEach(),for in 和 for of
1、forEach:忽略属性值;不允许break跳出循环
var myArray = [1,2,3,4];
myArray.desc = "for number";
myArray.forEach(value=>console.log(value)); // 打印1 2 3 4 ,忽略属性值,不打印属性desc
2、for in:循环数组的下标或对象属性的名称键值对
var myArray = [1,2,3,4];
myArray.desc = "for number";
for(var n in myArray){
console.log(n); // 0 1 2 3 desc
console.log(myArray[n]); // 1 2 3 4 for number
}
3、for of:忽略属性;可以break
// example1
var myArray = [1,2,3,4];
myArray.desc = "for number";
for(var n of myArray){
console.log(n); // 1 2 3 4
}
// example2
var myArray = [1,2,3,4];
myArray.desc = "for number";
for(var n of myArray){
if(n>2) break;
console.log(n); // 1 2
}
// example3
for(var n of "for number"){
console.log(n); // for number
}
介绍TypeScript中的面向对象特性
类(Class):类是TypeScript的核心,使用TypeScript开发时,大部分代码都是写在类里面的。
这里会介绍类的定义,构造函数,以及类的继承
构造函数里name属性必须声明权限控制符
1)super:调父类的构造函数
2)调父类的其他方法
// example1
class Person {
name; // 未声明权限控制符,报错,转化成ES5不报错
eat() {
console.log("im eating");
}
}
var p1 = new Person();
p1.name = "batman";
p1.eat();
var p2 = new Person();
p2.name = "superman";
p2.eat();
// example2
class Person {
private name;
private eat() {
console.log("im eating");
}
}
var p1 = new Person();
p1.name = "batman"; // 报错
p1.eat(); // 报错
var p2 = new Person();
p2.name = "superman"; // 报错
p2.eat(); // 报错
// example4
class Person {
protected name;
protected eat() {
console.log(name);
}
}
var p1 = new Person();
p1.name = "batman"; // 报错
p1.eat(); // 报错
var p2 = new Person();
p2.name = "superman"; // 报错
p2.eat(); // 报错
// example5
class Person {
constructor(){
console.log("haha");
}
name;
eat() {
console.log(this.name);
}
}
var p1 = new Person();
p1.name = "batman";
p1.eat();
var p2 = new Person();
p2.name = "superman";
p2.eat();
// example6
class Person {
name;
constructor(name:string){
this.name = name;
}
eat() {
console.log(this.name);
}
}
var p1 = new Person("batman");
p1.eat();
var p2 = new Person("superman");
p2.eat();
// example7
class Person {
constructor(public name:string){
}
eat() {
console.log(this.name);
}
}
var p1 = new Person("batman");
p1.eat();
var p2 = new Person("superman");
p2.eat();
// example8 继承
class Person {
constructor(public name:string){
console.log("haha");
}
eat() {
console.log("im eating");
}
}
class Employee extends Person {
constructor(name: string, code: string) {
super(name);
console.log("xixi");
this.code = code;
}
code: string;
work() {
super.eat();
this.doWork();
}
private doWork() { // 不让外部调用
console.log("im working");
}
}
var e1 = new Employee("name","1");
e1.work();
泛型(generic):参数化的类型,一般用来限制集合的内容
Array:数组泛型只能放某个类型的数据(如Person)
class Person {
constructor(public name:string){
console.log("haha");
}
eat() {
console.log("im eating");
}
}
class Employee extends Person {
constructor(name: string, code: string) {
super(name);
console.log("xixi");
this.code = code;
}
code: string;
work() {
super.eat();
this.doWork();
}
private doWork() { // 不让外部调用
console.log("im working");
}
}
var workers: Array = [];
workers[0] = new Person("zhangsan");
workers[1] = new Employee("lisi",2);
workers[2] = 2; // 报错
接口(Interface):用来建立某种代码约定,使用其它开发者在调用某个方法或创建新的类时必须遵循接口所定义的代码约定
1)声明属性:多传或少传属性,都会报错
2)接口里声明方法,类实现接口里的方法
// example1
interface IPerson {
name: string;
age: number;
}
class Person {
constructor(public config: IPerson){
}
}
var p1 = new Person({
name: "zhangsan",
age: 18,
xxx: "xxx" // 报错
});
// example2
interface Animal {
eat();
}
class Sheep implements Animal {
eat() {
console.log("i eat grass");
}
}
class Tiger implements Animal {
eat() {
console.log("i eat meat");
}
}
一个文件就是一个模块
模块内部有两个关键字:import和export
模块(Module):模块可以帮助开发者将代码分割为可重用的单元。开发者可以自己决定将模块中的哪些资源(类、方法、变量)暴露出去供外部使用,哪些资源只在模块内使用
// a.ts
export var prop1;
var prop2;
export function func1() {
}
function func2() {
}
export class Clazz1 {
}
class Clazz2 {
}
// b.ts
import {prop1, func1, Clazz1} from "./a";
console.log(prop1);
func1();
new Clazz1();
export function func3 {
}
Agular @注解
注解(annotation):注解为程序的元素(类、方法、变量)加上更直观更明了的说明,这些说明信息语程序的业务逻辑无关,而是供指定的工具或框架使用的
类型定义文件(*.d.ts):类型定义文件用来帮助开发者在TypeScript中使用已有的JavaScript的工具包。如JQuery
https://github.com/DefinitelyTyped/DefinitelyTyped/ 从branches可以找到jquery/index.d.ts
https://github.com/typings/typings
// a.ts
export var prop1;
var prop2;
export function func1() {
}
function func2() {
$('#xxxx').hide(); // 报错,$:unresolved function or method $(),添加文件index.d.ts,可用
}
export class Clazz1 {
}
class Clazz2 {
}
// b.ts
import {prop1, func1, Clazz1} from "./a";
console.log(prop1);
func1();
new Clazz1();
export function func3 {
}