所有函数实例都具有 Function 中的实例成员:

    • length属性:得到函数形参数量。
    • apply方法:调用函数,同时指定函数中的 this 指向,参数以数组的形式来传递。
    • call方法:调用函数,同时指定函数中的 this 指向,参数以参数列表的形式来传递。
    • bind方法:返回一个新函数,该函数中的 this 始终指向指定的值。
    • test.html
    1. var test = function (a, b) {}
    2. test.length; // => 2

    test.length 表示函数形参的个数。

    • test.html
    1. function sayHello(a, b) {
    2. console.log(this.name, this.age);
    3. }
    4. var user1 = {
    5. name: "foo",
    6. age: 18
    7. };
    8. /* 要求打印 user1 中的 name 和 age */
    9. // 错误做法:
    10. sayHello(); // 因为 this ==> window 所以不行
    11. user1.sayHello(); // 因为 user1 里面没有 sayHello 这个函数 所以不行。
    12. // 正确做法:
    13. sayHello.apply(user1); // "foo" 18
    14. sayHello.call(user1); // "foo" 18
    15. var newFun = sayHello.bind(user1);
    16. newFun(); // "foo" 18
    17. user1.sayHello = sayHello;
    18. user1.sayHello(); // "foo" 18

    apply、call、bind 它们都能改变函数中 this 的指向,但是,也存在一些区别。其中 apply、call 会在绑定 this 的同时,将函数给调用一遍,而 bind 仅仅是返回一个新的,并且绑定好 this 的函数,并没有把函数个调用一遍。

    • test.html
    1. function sayHello(a, b) {
    2. console.log(this.name, this.age, a, b);
    3. }
    4. var user1 = {
    5. name: "foo",
    6. age: 18
    7. };
    8. sayHello.apply(user1, [1, 2]); // => "foo" 18 1 2
    9. sayHello.call(user1, 1, 2); // => "foo" 18 1 2
    10. var newFunc = sayHello.bind(user1, 1, 2);
    11. newFunc(); // => "foo" 18 1 2
    • apply:参数以数组的形式传递;
    • call:参数以参数列表的形式传递;
    • bind:参数以参数列表的形式传递;

    注意:bind 不仅可以绑定 this 的指向,还可以绑定形参。


    arguments:在函数中使用,获取该函数调用时,传递的所有参数。arguments 是一个类数组(也称为伪数组,没有通过 Array 构造函数创建的类似于数组结构的对象称为类数组),伪数组会缺少大量的数组实例方法。arguments 数组中的值,会与对应的形参映射。

    • test.html
    1. var test = function abc(a, b) {
    2. arguments[0] = "abc";
    3. b = 123;
    4. a; // => "abc"
    5. b; // => 123
    6. arguments; // => ["abc", 123]
    7. }
    8. test(1, 2);
    1. var test = function abc(a, b) {
    2. arguments[0] = "abc";
    3. b = 123;
    4. a; // => undefined
    5. b; // => 123
    6. arguments; // => ["abc"]
    7. }
    8. test(); // 没有传递参数,所以 arguments 不会与形参映射
    1. var test = function abc(a, b) {
    2. arguments[0] = "abc";
    3. b = 123;
    4. a; // => "abc"
    5. b; // => 123
    6. arguments; // => ["abc", 123]
    7. }
    8. test(undefined, 2);

    从上面的例子可以看出,arguments 是否会与形参之间形成映射关系,还得看我们在调用函数的时候,是否有传入参数。若我们传入了参数,那对应位置的形参就会与 arguments 形成映射关系,否则不会有映射。

    • test.html
    1. function test() {
    2. arguments; // => [1, 2, 3, 4, 5]
    3. Array.isArray(arguments); // => false
    4. //将 arguments 转换为真数组
    5. var newArr = [].slice.call(arguments);
    6. Array.isArray(newArr); // => true
    7. newArr; // => [1, 2, 3, 4, 5]
    8. }
    9. test(1, 2, 3, 4, 5);

    通常,可以利用 apply、call 方法,将某个伪数组转换伪真数组。

    • Array.isArray() 用于判断数组是真数组还是伪数组。

    将一个伪数组转换为一个真数组的方式还有很多,后面会接触到,比如 es6 提供的展开运算符,就可以很轻易的实现,至于其他方式,这里就不作过多介绍了。

    1. function test() {
    2. arguments; // => [1, 2, 3, 4, 5]
    3. Array.isArray(arguments); // => false
    4. const newArr = [...arguments];
    5. newArr; // => [1, 2, 3, 4, 5]
    6. Array.isArray(newArr); // => true
    7. }
    8. test(1, 2, 3, 4, 5);