JavaScript Function

函数名

在 js 中函数也是对象,所以函数名可以认为是指向函数对象的一个变量。

this

在非strict模式下:

非对象中函数的 this 指向 global对象或 window对象,对象中方法的 this 指向该对象,对象方法中嵌套的函数中的 this 又指向了 global对象或 window对象。

在strict模式下:

非对象中函数的 this 为 undefined,对象中方法的 this 指向该对象,对象方法中嵌套的函数中的 this 又指向了 undefined。

返回值

JavaScript函数总会有一个返回值,如果不使用 return 语句主动返回一个值,则函数默认会返回 undefined。

参数

js 函数允许传入任意多个参数,如果传参多余,多余的参数不使用的话将不会起作用,如果传参不足,不足的参数默认会被定义为 undefined。

函数还有一个内置对象 arguments,arguments类似于一个数组但不是数组,包含了调用函数时传入的参数。

function f(a, b, c) {
    for (let i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
}
f(1, 2, 3);

/*
输出如下:
1
2
3
*/

...rest参数

...rest是ES6中引进来的。rest参数只能写在所有参数的最后,并且要用...来标识。如果传入的参数多余定义的参数,则多余的参数会以数组的形式保存在rest变量中,否则rest将会接收到一个空数组。

var f = function(a, b, ...rest) {
    return rest;
}
console.log(f(1, 2, 3));    //[ 3 ]

toString()

该方法将函数作为一个字符串返回。

function f(){
    console.log("How are you?");
}
console.log(typeof f.toString());
console.log(f.toString());

/* 输出如下: string function f(){ console.log("How are you?"); } */

apply()

该方法能够控制函数中 this 的指向。它接受两个参数,第一个参数就是需要绑定的对象名,第二个参数是Array,用来存放函数本身的参数。

var f = function(str) {
    return this.a + str;
};
var myObject = {
    a: "hello"
};
console.log(f.apply(myObject, [" world"]));    //hello world

call()

该方法也能够改变函数中 this 的指向,它和 apply() 的区别就是在传参方式上,apply 通过数组传参,而 call 按原始方式进行传参。当然第一个参数还是方法需要绑定的对象名。

var f = function(str) {
    return this.a + str;
};
var myObject = {
    a: "hello"
};
console.log(f.call(myObject, " world"));    //hello world

装饰器

通过 apply() 和 call() 方法我们可以动态的改变函数的行为,即使是内置函数。因此我们可以通过它们的这个特性,来给已经存在的函数增加一些功能。

// 统计调用parseInt()函数的次数
var count = 0;
var oldParseInt = parseInt;    //save original parseInt
parseInt = function() {    //decorate parseInt
    count++;
    return oldParseInt(null, arguments);    //通过return的返回值使parseInt函数保留了原来的功能
};
parseInt('10');
parseInt('10');
parseInt('10');
console.log(count);    //3

高阶函数

如果一个函数的参数中包含另一个函数,则我们称原函数为高阶函数。我们知道函数可以保存在变量中,而变量又可以作为参数进行传递,所以高阶函数是可以理解的。高阶函数的两个典型应用是 Array 的 map() 和 reduce()。