一、什么是函数调用?

函数调用就像你请别人帮你做事:你先定义好这个人能做什么(函数定义),然后在需要的时候请他去做(函数调用)。

// 1. 定义一个函数(教别人做事)
function greet() {
  console.log(“你好!”);
}

// 2. 调用函数(请人做事)
greet(); // 输出: “你好!”
小贴士: 在函数名后面加上小括号 () 表示调用函数。没有小括号,函数不会执行。

二、函数调用的基本方式

1. 直接调用

最简单的调用方式,直接使用函数名加小括号:

sayHello();

2. 作为对象方法调用

当函数作为对象的属性时,称为方法:

let person = {
  name: “小明”,
  greet: function() {
    console.log(“你好,我是” + this.name);
  }
};

person.greet(); // 调用对象的方法

3. 使用new调用(构造函数)

创建新对象时使用:

function Person(name) {
  this.name = name;
}

let p = new Person(“小红”);

4. 间接调用(call/apply/bind)

改变函数执行时的上下文:

function introduce() {
  console.log(“我是” + this.name);
}

let obj = { name: “小李” };
introduce.call(obj); // 输出: “我是小李”

三、函数调用的核心概念

1. 参数传递

函数可以接受输入值(参数):

function add(a, b) {
  return a + b;
}

let result = add(5, 3); // 传入5和3
console.log(result); // 输出: 8

2. 返回值

函数可以通过return语句返回结果:

function multiply(x, y) {
  return x * y;
}

let product = multiply(4, 5); // → 20

3. this关键字

this的值取决于函数的调用方式:

function showContext() {
  console.log(this);
}

showContext(); // this指向window/global

let obj = { method: showContext };
obj.method(); // this指向obj

let instance = new showContext(); // this指向新创建的对象
重要理解: this不是固定的,它在函数被调用时才确定,指向调用该函数的对象。

四、特殊函数调用方式

1. 匿名函数调用

没有名字的函数,通常立即执行:

// 立即调用函数表达式 (IIFE)
(function() {
  console.log(“这个函数立即执行”);
})();

2. 箭头函数调用

ES6新增的简洁语法,没有自己的this:

const sum = (a, b) => a + b;
console.log(sum(2, 8)); // 10

let object = {
  value: 42,
  getValue: function() {
    const inner = () => {
      console.log(this.value); // 箭头函数继承外层this
    };
    inner();
  }
};
object.getValue(); // 42

3. 回调函数调用

将函数作为参数传递给另一个函数,在某个时刻被调用:

function doHomework(subject, callback) {
  console.log(“开始做” + subject + “作业”);
  callback(); // 调用回调函数
}

doHomework(“数学”, function() {
  console.log(“作业做完啦!”);
});
// 输出:
// 开始做数学作业
// 作业做完啦!

函数调用方式对比

📌

直接调用

this → 全局对象

👤

方法调用

this → 调用对象

🏗️

构造函数

this → 新创建的对象

🎯

间接调用

this → 指定的对象

五、常见错误与注意事项

1. 忘记调用函数

function sayHi() {
  console.log(“Hi!”);
}

sayHi; // 错误:没有执行,只是引用函数
sayHi(); // 正确:执行函数

2. 参数数量不匹配

function divide(a, b) {
  return a / b;
}

divide(10); // b是undefined → 10 / undefined = NaN
divide(10, 2, 5); // 第三个参数会被忽略

3. this指向问题

let counter = {
  count: 0,
  increment: function() {
    setTimeout(function() {
      this.count++; // 错误!这里的this是window
    }, 1000);
  }
};
counter.increment(); // 不会正确增加count
解决方法: 使用箭头函数或提前保存this
// 方法1:使用箭头函数
increment: function() {
  setTimeout(() => {
    this.count++;
  }, 1000);
}

// 方法2:保存this
increment: function() {
  let self = this;
  setTimeout(function() {
    self.count++;
  }, 1000);
}