函数声明和函数表达式
JavaScript 中,有两种常见的定义函数的方式:函数声明(Function Declaration)和函数表达式(Function Expression)。
在 TypeScript 中,要对输入和输出进行约束,输入多余的(或者少于要求的)参数,都是不被允许的。
// 函数声明(Function Declaration)
function sum(x: number, y: number): number {
return x + y;
}
// 函数表达式(Function Expression)
//推断类型
let mySum = function (x: number, y: number): number {
return x + y;
};
//完整类型
let myAdd: (baseValue: number, increment: number) => number =
function(x: number, y: number): number { return x + y; };
//在 TypeScript 的类型定义中,=> 用来表示函数的定义,而ES6 中,=> 叫做箭头函数。
可选参数
与接口中的可选属性类似,用 ? 表示可选的参数。可选参数必须接在必需参数后面。
function buildName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');
参数默认值
在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数。
添加默认值,不受可选参数必须接在必需参数后面的限制。
function buildName(firstName: string = 'Tom', lastName: string) {
return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let cat = buildName(undefined, 'Cat');
剩余参数
ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数),剩余参数语法允许将一个不确定数量的参数作为一个数组传入。
//Typescript
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
重载
利用联合类型,不能够精确的表达,即输入输出类型不能一一对应。重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。
如果参数类型不同,则参数类型应设置为 any。参数数量不同可以将不同的参数设置为可选。
注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
参数类型不同:
function disp(string):void;
function disp(number):void;
参数数量不同:
function disp(n1:number):void;
function disp(x:number,y:number):void;
参数类型顺序不同:
function disp(n1:number,s1:string):void;
function disp(s:string,n:number):void;
用接口定义函数的形状
采用函数表达式|接口定义函数的方式时,对等号左侧进行类型限制,可以保证以后对函数名赋值时保证参数个数、参数类型、返回值类型不变。
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
匿名函数
匿名函数是一个没有函数名的函数。
匿名函数在程序运行时动态声明,除了没有函数名外,其他的与标准函数一样。
将匿名函数赋值给一个变量,这种表达式就成为函数表达式。
var res = function(a:number,b:number) {
return a*b;
};
console.log(res(12,2))
匿名函数自调用(在函数后使用 () 即可):
(function () {
var x = "Hello!!";
console.log(x)
})()
构造函数
TypeScript 支持使用 JavaScript 内置的构造函数 Function() 来定义函数。
通过new 函数名来实例化对象的函数叫构造函数。任何的函数都可以作为构造函数存在。之所以有构造函数与普通函数之分,主要从功能上进行区别的,构造函数的主要功能为初始化对象,特点是和new一起使用。new就是在创建对象,从无到有,构造函数就是在为初始化的对象添加属性和方法。构造函数定义时首字母大写(规范)。
对new理解:new 申请内存, 创建对象,当调用new时,后台会隐式执行new Object()创建对象。所以,通过new创建的字符串、数字是引用类型,而是非值类型。
ES6 class的写法实质就是构造函数。class 为构造函数的语法糖,即class的本质是构造函数。class的继承 extends本质为构造函数的原型链的继承。通过class定义的类和通过构造函数定义的类二者本质相同。并且在js执行时,会将第一种转会为第二种执行。
语法格式如下:
var res = new Function ([arg1[, arg2[, ...argN]],] functionBody)
参数说明:
- arg1, arg2, ... argN:参数列表。
- functionBody:一个含有包括函数定义的 JavaScript 语句的字符串。
var myFunction = new Function("a", "b", "return a * b");
var x = myFunction(4, 3);
console.log(x);
递归函数
递归函数即在函数内调用函数本身。
使用递归的时候,函数是声明式的写法,避免出现 test is not a function 这种错误。
function factorial(number) {
if (number <= 0) { // 停止执行
return 1;
} else {
return (number * factorial(number - 1)); // 调用自身
}
};
console.log(factorial(6)); // 输出 720
Lambda 函数
Lambda 函数也称之为箭头函数。
箭头函数表达式的语法比函数表达式更短。
单个参数 () 是可选的,无参数时可以设置空括号。
函数只有一行语句:
( [param1, parma2,…param n] )=>statement;
//实例
var foo = (x:number)=>10 + x
console.log(foo(100)) //输出结果为 110