![](https://img.haomeiwen.com/i2979799/5e3d652a96c7b5b2.jpg)
函数是一种特殊的对象,可以被调用。TS 里的函数和原生,ES 6 里的函数差不太多,只是多了一些其他功能。
基础
先来看一个简单的函数例子。
let say = function () {
console.log('hi')
}
函数类型
TS 里可以自定义传入参数的类型以及函数返回的类型。下面定义加法函数,里面声明了传入参数的类型是 number
,函数返回的类型也是 number
。
function add(a: number, b: number): number {
return a + b
}
TS 函数还可以设置可选参数。如果不设置可选参数,那么所有定义的参数都要传入。
function add(a: number, b: number): number {
return a + b
}
add(1) // 报错,要传入 b
function add1(a: number, b?: number):number {
return a + 1 + b
}
add(1) // 不报错,返回结果是 NaN
add(1, 2) // 不报错,返回结果是 4
对于函数返回类型,可以设置多个类型。但是要注意的是 undefined
是所有类型的大哥,如果 void
或者不声明返回类型,则返回 undefined。
function add(a: string, b: string, flag: boolean): number|string {
if (flag) {
return a + b
}
else {
return parseInt(a) + parseInt(b)
}
}
console.log(sub('1', '2', true)) // "12"
console.log(sub('1', '2', false)) // 3
默认参数值
这个其实是 ES 6 的特性,可以给函数加默认参数值。
function add(a: number, b = 2): number {
return a + b
}
console.log(add(1, 2)) // 3
console.log(add(1)) // 3
上面就设置了参数值的默认值是 2,所以结果都一样。要注意的是设置了默认值后就不需要设置类型了,因为 TS 可以做类型推断。
arguments
这是函数里类似数组的一个特殊对象,里面存放的是函数传入参数,很好理解。
function add(a: number, b: number): number {
// a, b 是形式参数
// return a + b
return arguments[0] + arguments[1]
}
add(100, 200) // 3
上面的 arguments
是如下结构,注意:不是数组,是对象,只是长得像数组。
arguments = {
0: 100,
1: 200,
length: 2
}
this
JS 里一直说的函数执行环境 this
在 TS 看来是一个变量。其实学习 JS 的时候总有人说 this
是环境变量或者上下文。
let obj = {
fn: function() {
console.log(this)
}
}
obj.fn()
以前我总有个疑问,上面的执行结果是 this = obj,但是按那些人说的 “执行环境” 不就是应该是这几行代码的执行环境么?那应该浏览器呀,如果是命令行那就是全局变量 Global,根本说不通!至于上下文真是醉了。
this 其实是一个函数的传入参数而已,下面两者调用相等。
let c = add(100, 200)
let d = add.call(undefined, 100, 200)
call
的第一个参会赋值到该函数内置的 this
变量,后面是函数传入的参数,它们则会赋值给 arguments
。下面简单实现说到的“赋值”。
function call(outside_this, arg1, arg2, ...) {
// 如果不是严格模式,this 会被包装成一个对象,但是这里不影响理解
let this = outside_this
let = arguments = {
0: arg1,
1: arg2,
length: 2
}
执行函数体...
}
这里不要将 this
和 arguments
看成是关键字,他们只不是变量而已,也是根据外界传入的参数来生成的。所以对于 this
是执行环境的说法是不对的,this
的指向应该看外界是怎么去调用 call
,传入第一个参数是什么才是正解。
那我怎么知道外界怎么调用 call
呢?别人写代码都是 add()
,推会闲得蛋疼去写成 add.call()
这种形式啊。所以要 死记硬背!,否则没法了。
没想到吧,网上博客说的可以推算出来,推算个 🐔儿,这玩意本来就是要记的,要不坑多了自己就知道了。下面说说常用的 this
指向。
指向浏览器
下面的 this
是指向浏览器器的全局亦是 Window
。
function fn() {
console.log(this)
}
fn()
可以看成如下调用:
fn.call(Window)
Node
在命令行下执行上面的代码 this
会指向 Global 对象。
可以看成如下调用:
fn.call(Global)
严格模式
这个可以了解一下,因为没人会写严格模式,除非写库的人。严格模式下,如果不在 call
显式传入第一个参数,那么就是 undefined,这个其实更好理解一点,因为不传肯定是 undefined 嘛。非严格模式下 JS 总是喜欢乱传搞得我们小白很蒙蔽。
重载
TS 的重载和 Java 的差不多,就是可以对调用同一个函数的时候传入不同的参数。但是重载的函数参数数目应该要是一样的。
function fn() {
'use strict'
console.log(this) // undefined
}
fn()
function add(n1: number, n2: number);
function add(n1: string, n2: string)
function add(n1, n2) {
return n1 + n2
}
// 3
add(1, 2)
// 12
add('1', '2')
// 12
add(1, '2') // 报错
网友评论