js中的函数进价

二. 函数进阶

2.1 函数的创建方式

  • 函数声明

    1
    2
    3
    function fn () {
    // 函数体
    }
  • 函数表达式

    1
    2
    3
    var fn = function () {
    // 函数体
    };
  • 区别

    • 预解析时,函数声明创建的函数整体会提升到所在执行环境【作用域】的顶部。
    • 预解析时,函数表达式创建的函数,仅仅提升变量名到所在执行环境【作用域】的顶部。

2.2 函数本身也是对象

  • 函数创建的第三种方式:

    • 语法:
      var 变量名 = new Function(‘形参1’,’形参2’,….,’程序代码’);

    • 代码:

      1
      2
      3
      4
      var fn = new Function('a','b','alert(a + b);');
      console.log(fn instanceof Function); // true
      console.log(fn instanceof Object); // true
      fn(10,20); // 调用函数

2.3 函数内this指向不同的场景

this到底指向谁,是由程序在执行的过程中决定的。以下是关于this指向情况的基本整理

  • 普通函数调用时,this指向window。

    1
    2
    3
    4
    5
    6
    // 定义一个函数
    function fn () {
    console.log(this);
    }
    // 调用
    fn(); // this→window
  • 构造函数调用时,this指向当前所创建的对象。

    1
    2
    3
    4
    5
    6
    7
    8
    // 构造函数
    function Student (name, age) {
    this.name = name;
    this.age = age;
    console.log(this);
    }
    var stu1 = new Student('张三', '李四'); // this →
    当前所创建的这个学生实例对象
  • 对象的方法调用时,this指向方法所属的对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 构造函数
    function Student (name, age) {
    this.name = name;
    this.age = age;

    }
    // 原型中的方法
    Student.prototype.sayHi = function() {
    console.log(this);
    console.log( this === stu1);
    };
    var stu1 = new Student('张三', '李四');
    stu1.sayHi(); // this → stu1
  • 事件绑定的方法,this 指向事件源

    1
    2
    3
    4
    5
    6
    // id为box的div元素对象
    var box = document.getElementById('box');
    // 为box注册事件
    box.onclick = function () {
    console.log(this);
    };
  • 定时器函数,this指向window

    1
    2
    3
    setInterval(function() {   // 省略了window
    console.log(this);
    }, 500);

2.4 改变函数内的this指向【掌握】

  • 为什么要改变this ?
    ​ 例如:我们经常在定时器外部备份 this 引用,然后在定时器函数内部使用外部 this 的引用。

  • 改变this的方式:函数有三个方法可以改变内部的this:call、apply、bind。

  • call方法

    • 语法:
      函数名.call(thisArg[, arg1[, arg2[, …]]]);

    • 参数

      • thisArg,在 函数运行时指定的 this 值。若传null或undefined,则函数内部this指向window
      • arg1, arg2, …指定的参数列表
    • 应用

      • ① 借用构造函数。

      • ② 借用其他对象中的方法。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        var obj = {
        0: 100,
        1: 200,
        2: 300,
        3: 400,
        length: 4
        }
        // obj.push(500); // 报错 对象中不存在这个方法
        // 借用数组的
        Array.prototype.push.call(obj,500);
        console.log(obj);

  • apply方法

    • 语法:
      函数名.apply(thisArg, [argsArray])

    • 参数:

      • thisArg,在 函数运行时指定的 this 值。若传null或undefined,则函数内部this指向window
      • argsArray,是一个数组,数组中存放函数调用时需要传入的实参。
    • 应用:

      • 和call方法一样,唯一不同的时,函数或方法被借用时,apply以数组的方式存放实参。

        1
        2
        3
        var nums = [11,66,33,44,55,77,22];
        var max = Math.max.apply(Math,nums);
        console.log(max);

  • bind方法

    • 语法:
      var 变量 = 函数名.bind(thisArg,[, arg1[, arg2[, …]]]);

    • 参数:

      • 语法:
        var 变量名 = 函数名.call(thisArg[, arg1[, arg2[, …]]]);

      • 参数:

        • thisArg,在 函数运行时指定的 this 值。若传null或undefined,则函数内部this指向window
        • arg1, arg2, …指定的参数列表
      • 应用:

        • 和call使用方式一样,不一样的时,使用bind时,借用的函数不会被立即执行,而是返回一个新的函数,若要执行,需要自己调用。

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          var obj = {
          age: 18
          };
          // id为box的div元素对象
          var box = document.getElementById('box');
          // 为box注册事件
          box.onclick = function () {
          console.log(this.age);
          }.bind(obj);
          setInterval(function() {
          console.log(this.age);
          }.bind(obj), 500);

2.5 函数的其他成员【了解】

  • arguments
    • 实参集合
  • caller
    • 函数的调用者
  • length
    • 形参的个数
  • name
    • 函数的名称
1
2
3
4
5
6
7
8
9
10
11
12
13
function fn(x, y, z) {
console.log(fn.length) // => 形参的个数
console.log(arguments) // 伪数组实参参数集合
console.log(arguments.callee === fn) // 函数本身
console.log(fn.caller) // 函数的调用者
console.log(fn.name) // => 函数的名字
}

function f() {
fn(10, 20, 30)
}

f()
文章目录
  1. 1. 二. 函数进阶
    1. 1.1. 2.1 函数的创建方式
    2. 1.2. 2.2 函数本身也是对象
    3. 1.3. 2.3 函数内this指向不同的场景
    4. 1.4. 2.4 改变函数内的this指向【掌握】
    5. 1.5. 2.5 函数的其他成员【了解】
|