字符串的新特性
-
多行字符串
使用``实现多行字符串
var content = `aaaa
bbbb
ccccc`;
编译成js代码为:
var content = "aaaa\nbbbb\nccccc";
-
字符串模板
其实和多行字符串差不多
var mynane = "jack";
var getName = function () {
return "jack";
}
console.log(`<div>
<span>${mynane}</span>
<span>${getName()}</span>
</div>`);
console.log(`hello${mynane}`);
console.log(`hello${getName()}`);
编译js代码:
var mynane = "jack";
var getName = function () {
return "jack";
};
console.log("<div>\n<span>" + mynane + "</span>\n<span>" + getName() + "</span>\n</div>");
console.log("hello" + mynane);
console.log("hello" + getName());
-
自动拆分字符串
function test(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var myname = "jack";
var getAge = function () {
return 18;
}
test`hello my name is ${myname},i'm${getAge()}`
打印结果:
参数新特性 之 参数类型
- 参数类型:在参数名称后面使用冒号来指定参数的类型
例如:string类型的,当赋值number类型时,报错
2.类型推断机制
例如:当我没有指定类型时,第一次给变量赋值为string
类型时,当我修改这个变量为number
类型,就会报错.
-
any
类型
当我赋值任何类型时,都不会报错;
上面的例子,当我把alias的类型指定为any
时,就不会报错了;
- 其他类型:
number
数字类型 ,boolean
布尔类型 ,void
类型
number
类型
var age: number = 13;
boolean
布尔类型
var man: boolean = true;
void
类型: 用于定义函数返回类型等
定义函数的返回类型为void
类型,当函数有返回值时,报错!,说明他不需要有任何类型的返回值.
- 自定义类型
自定义一个对象类型
class Person {
name: string;
age: number;
}
var zhangsan: Person = new Person();
zhangsan.name = 'jack';
zhangsan.age = 18;
参数新特性 之 默认参数
在参数声明后面用等号来指定参数的默认值
1.只要在等号后边赋上默认值即可
var myname: string = "张三";
2.给方法的变量指定默认值
- 给方法参数指定类型
function test(a:string, b:string, c:string) {
console.log(a);
console.log(b);
console.log(c);
}
test("xxx","yyy","zzz");
-
当调用上面的方法,如果少传一个参数,就会报错
- 如何解决上面函数报错的问题呢? 可以给第三个参数指定一个默认值; 这样如果第三个参数不填,就会调用默认值;
注意: 带默认值的参数一定要声明在"最后面";
参数新特性 之可选参数
在方法的参数声明后面用问号来标明此参数为可选参数
以上面的方法为例,在b
参数后面写上?
,定义为可选参数;
function test(a: string, b?: string, c: string = "jack") {
console.log(a);
console.log(b);
console.log(c);
}
test("xxx");
注意:必选的参数,不能在可选参数的后面
函数新特性
-
Rest and Spread
操作符: ①.用来声明任意数量的方法参数
function func1(...args) {
args.forEach(function (arg) {
console.log(arg);
})
}
func1(1, 2, 3); // 1, 2, 3
func1(5, 6, 7, 8, 9); // 5, 6, 7, 8, 9
②.Rest and Spread
操作符:另外一个作用:展开运算符
当然此语法TypeScript
还不支持,会报错,但是转成js语法后可正常编译.
function func1(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
}
var args = [1, 2];
func1(...args); //执行结果: 1, 2, undefined
var args2 = [7, 8, 9, 10, 11];
func1(...args2); //执行结果: 7 , 8, 9
上述代码编译成js语法后
function func1(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
}
var args = [1, 2];
func1.apply(void 0, args);
var args2 = [7, 8, 9, 10, 11];
func1.apply(void 0, args2);
-
generator
函数:控制函数的执行过程, 手工暂停和恢复代码执行;
类似于断点调试(目前ts
还不支持,它是ES6
的一部分)
在babel
编辑器中
通过*号function* xxx()
声明 generator
函数
function* doSomething(){
console.log("start");
yield; // 类似于一个断点
console.log("finish");
}
var func1 = doSomething();
func1.next(); // 代表函数执行,第一次走,函数会停在yield断点处;
func1.next();// 第二次走,会越过yield断点继续往下执行;
又例如:下面的函数,当价格小于limitPrice
时,购买股票(点击查看源码)
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}`);
3.destructuring
析构表达式:通过表达式,将对象或者数组拆解成任意数量的变量
也就是之前了解的"结构赋值"
①:对象中的使用
function getStock() {
return {
code: "IBM",
price: 100
}
}
// ES5
var stock = getStock();
var code = stock.code;
var price = stock.price;
// ES6
// var { code, price } = getStock();
// 也可以设置别名
var { code: codex, price } = getStock();
// 调用别名
console.log(codex); // IBM
对象中多层嵌套属性
function getStock() {
return {
code: "IBM",
price: {
price1: 200,
price2:400
},
aaa: "xixi",
bbb: "hahah"
}
}
// code: codex 设置别名
var { code: codex, price: { price1, price2 } } = getStock();
// 调用别名
console.log(codex); // IBM
console.log(price1); // 200
②. 数组中析构表达式的使用
var array1 = [1, 2, 3, 4];
var [number1, number2] = array1;
console.log(number1); // 1
console.log(number2); // 2
取数组中的后两个值
var array1 = [1, 2, 3, 4];
var [, , number1, number2] = array1;
console.log(number1); // 3
console.log(number2); // 4
举一反三
var array1 = [1, 2, 3, 4];
var [number1, , , number2] = array1;
console.log(number1); // 1
console.log(number2); // 4
析构表达式和Rest and Spread
操作符共同使用
var array1 = [1, 2, 3, 4];
var [number1, number2, ...others] = array1;
console.log(number1); // 1
console.log(number2); // 2
console.log(others); // 数组 [3, 4]
函数中的使用
var array1 = [1, 2, 3, 4];
function doSomething([number1, number2, ...others]) {
console.log(number1); // 1
console.log(number2); // 2
console.log(others); // 数组 [3, 4]
}
doSomething(array1);
表达式和循环
1.箭头表达式:用来声明匿名函数,消除传统匿名函数的this指针问题
-
简单使用
//1.1 => 箭头后面如果只有一行,不用写大括号的 arg1 + arg2;
var sum1 = (arg1, arg2) => arg1 + arg2;
//1.2 如果是多行
var sum2 = (arg1, arg2) => {
return arg1 + arg2;
}
//1.3 没有参数的箭头函数
var sum3 = () => {
}
//1.4 只有一个参数的箭头函数,参数可以省略()
var sum4 = arg1 => {
console.log(arg1);
}
// 1.5 箭头函数的简单使用
var myArray = [1, 2, 3, 4];
// 筛选出数组中的偶数
console.log(myArray.filter(value => value % 2 == 0)); // 数组[2, 4]
-
消除传统匿名函数的this指针问题
function getStock(name: string) {
this.name = name;
setInterval(function () {
console.log(`name is ${this.name}`); //打印结果: name is ,this.name的值为空
},1000);
}
var stock = new getStock("IBM");
function getStock2(name: string) {
this.name = name;
setInterval(() => {
console.log(`name is ${this.name}`); //打印结果:name is IBM,这下this.name就有值了,这样更符合开发者的编程习惯
}, 1000);
}
var stock2 = new getStock2("IBM");
- 循环
forEach()
,for in
和for of
,还有find()
forEach()
var myArray = [1, 2, 3, 4];
myArray.desc = "four number"; // 给数组添加属性,ts语法不支持
//注意:
//1.1 forEach()循环会去循环数组里面的元素,把属性忽略掉
//1.2 forEach()循环中间不能break(跳出循环)
myArray.forEach(value => console.log(value)); // 依次输出1,2,3,4
for in
var myArray = ["jack", "lucy", "lily", "tom"];
myArray.desc = "four people"; // 给数组添加属性,ts语法不支持
for (var n in myArray) {
// 注意 for in 循环的是集合的键,在此处指的是数组的下标
console.log(n); // 0, 1, 2, 3, desc
// 要想打印出数组的值
console.log(myArray[n]);// jack, lucy, lily, tom, desc
}
// 注意:for in 循环可以把数组的属性循环出来,这个行为很可能不是我们希望的行为
for of
var myArray = ["jack", "lucy", "lily", "tom"];
myArray.desc = "four people"; // 给数组添加属性,ts语法不支持
for (var name of myArray) {
console.log(name); // jack, lucy, lily, tom
}
// for of 和 for in的区别:for of可以忽略掉数组的属性,for of循环的是集合的值, for in 循环的是键
for of
循环是可以被打断的
var myArray = ["jack", "lucy", "lily", "tom"];
myArray.desc = "four people"; // 给数组添加属性,ts语法不支持
for (var name of myArray) {
if (name == "lily") break;// 当循环到name==lily时,跳出循环
console.log(name); // jack, Lucy
}
for of
循环字符串
var myaddress = "Shanghai";
for (var char of myaddress) {
console.log(char); // 打印结果: s ,h,a,,n,g,h,a,i
}
for of
还可以循环对象,map
等
find()
函数,通过条件查询出符合条件的
getStock(id: number): Stock {
return this.stocks.find(stock => stock.id === id);
}
TypeScript类
- 类 (class)
类是TypeScript
的核心,使用Typescript
开始时,大部分代码都是写在类里面的.
-
类的定义
class Person{
name;
eat() {
console.log("i'm eatting");
}
}
// 类的实例化
var p1 = new Person();
p1.name = "batman";
p1.eat();
var p2 = new Person();
p2.name = "superman";
p2.eat();
// 一个类可以new出多个示例,他们拥有相同的属性和方法,但是属性的状态不同!
类的访问控制符: public
, private
, protected
public
: 默认是访问控制符,public的属性和方法都是可以在类的内部和外部访问到的.
private
: 私有的,只可以在类的内部被访问到,在类的外部是访问不到的!
protected
: 受保护的,受保护的属性和方法可以在类的内部和他的子类(继承)里边被访问到.
-
类的构造函数
constructor
:在类被实例化的时候调用,而且只会被调用一次,在外部是访问不到的!
例如:类的实例化时,必须传进来一个名字
class Person{
name;
constructor(name:string) {
this.name = name;
}
eat() {
console.log(this.name);
}
}
// 类的实例化
var p1 = new Person("batman");
p1.eat(); // batman
var p2 = new Person("superman");
p2.eat(); // superman
上面的方法等同于下面
class Person{
//public name:string 等同于生命了一个name属性
constructor(public name:string) {
}
eat() {
console.log(this.name);
}
}
// 类的实例化
var p1 = new Person("batman");
p1.eat(); // batman
var p2 = new Person("superman");
p2.eat(); // superman
- 类的继承
- extends:用来声明一种继承关系.
class Person{ constructor(public name:string) { } eat() { console.log(this.name); } } // Employee继承自Person,Employee类可以获得Person类的所有的属性和方法 class Employee extends Person{ // 可以指定新的属性和方法 code: string; work() { } } // el 同时拥有Person和Employee的属性方法 var el = new Employee("meimei"); el.eat(); el.code = "123"; el.work();
- super
调父类的构造函数
- extends:用来声明一种继承关系.
class Person{
constructor(public name:string) {
console.log("哈哈");
}
eat() {
console.log("I'm eatting");
}
}
class Employee extends Person{
constructor(name:string, code:string) {
super(name);// 调用父类的构造函数
this.code = code;
console.log("嘻嘻");
}
// 可以指定新的属性和方法
code: string;
work() {
// 在方法里面调用父类的方法
super.eat();
//调用自己方法
this.dowork();
}
dowork() {
console.log("I'm working");
}
}
// el 同时拥有Person和Employee的属性方法
var el = new Employee("meimei","123");
el.work();
面向对象 之 泛型
泛型 (generic
): 参数化的类型,一般用来限制集合的内容.
比如:下面的例子,尖括号里面的Person
就是泛型,他约定这个数组里面只能放Person
类型的数据;
var workers: Array<Person> = [];
泛型的具体使用:
class Person{
constructor(public name:string) {
console.log("哈哈");
}
eat() {
console.log("I'm eatting");
}
}
class Employee extends Person{
constructor(name:string, code:string) {
super(name);// 调用父类的构造函数
this.code = code;
console.log("嘻嘻");
}
// 可以指定新的属性和方法
code: string;
work() {
// 在方法里面调用父类的方法
super.eat();
//调用自己方法
this.dowork();
}
dowork() {
console.log("I'm working");
}
}
/**********************泛型的具体使用***********************/
var workers: Array<Person> = []; //指定了 workers类型为数组,且数组只能放Person类型的数据
workers[0] = new Person("zhangsan");
workers[1] = new Employee("lisi", "2"); // Employee是继承自Person,也可以放
workers[2] = 2;// 就会报红色警告
面向对象 之 接口(Interface)
接口(Interface):用来建立某种代码约定,使得其他开发者在调用某个方法或者创建新的类时,必须遵循接口所定义的代码约定;(js中没有,只有ts
中有)
- Interface 声明属性
// 声明接口
interface IPerson{
name: string;
age: number;
}
//声明一个类
class Person{
// 作用: 参数方法类型声明
// config: IPerson >>> IPerson类型的参数
constructor(public config: IPerson) {
}
}
// 实例化时,必须要传一个IPerson类型的对象进去
// 注意:多传一个属性和多传一个属性都会报错
var p1 = new Person({
name: "zhangsan",
age: 18
});
- Interface 声明方法
implements 实现的意思
// 声明一个方法
interface Animal {
eat();
}
// implements 作用:声明 Sheep 这个类实现 Animal 的接口
// 它必须实现 Animal 的eat()方法
class Sheep implements Animal{
eat() {
console.log("I eat grass");
};
}
class Tiger implements Animal{
eat() {
console.log("I eat meat");
};
}
面向对象 之 模块
模块(Module):模块可以帮助开发者将代码分割为可重用的单元.开发者可以自己决定将模块中的哪些资源(类,方法,变量)暴露出去供外部使用,哪些资源只在模块内使用.
在a.ts
中暴露一些属性,方法和类
// 有两个关键字支撑模块的特性: export import
// 对外暴露一些东西
export var prop1;
// 不对外暴露
var prop2;
// 对外暴露一个方法
export function func1() {
}
// 不对外暴露方法
function func2() {
}
// 对外暴露一个类
export class Class1 {
}
// 不对外暴露一个类
class Class2 {
}
在b.ts
中引用a的属性,方法和类
// 一个模块 既可以对外暴露(export)它的属性、方法和类,也可以import别人的属性、方法和类;
import {Class1, func1, prop1} from "./a";
console.log(prop1);
func1();
new Class1();
export function func3(){
}
面向对象 之 注解
注解(annotation): 注解为程序的元素(类, 方法, 变量)加上更直观更明了的说明, 这些说明信息与程序的业务逻辑无关,而是供指定的工具或框架使用的;
面向对象 之 类型定义文件(*.d.ts)