总所周知,JavaScript中有很多函数定义方式,如何“因地制宜”?(ˉ﹃ˉ)

一、为什么需要函数?先搞懂核心作用

想象你在厨房做饭:每次炒青菜都要重复 "洗菜→切菜→热油→下锅→调味" 这 5 步。如果写代码时重复的逻辑也手动敲三遍,不仅累还容易出错 ------ 这就是函数存在的意义:把重复代码打包成 "万能菜谱",随时调用

比如计算圆的面积,每次用都要写一遍公式,用函数封装后:

javascript 复制代码
function calculateArea(radius) {
  return 3.14 * radius * radius; // 封装核心逻辑
}
console.log(calculateArea(5)); // 调用时直接传参数,像查菜谱一样方便

二、新手必学的 4 种函数定义方式(附对比表格)

2.1 最 "直白" 的函数声明:function 关键字

语法长这样

php 复制代码
function 函数名(参数1, 参数2) { 
  // 函数体:写具体要做的事 
  return 结果; // 可选,有返回值时写
}

举个生活例子:像 "说明书式" 的菜谱,先写好步骤再用。

javascript 复制代码
// 定义:教电脑怎么打招呼
function sayHello(name) { 
  return `你好,${name}!`; 
}
// 调用:直接喊函数名
console.log(sayHello("小明")); // 输出:你好,小明!

什么时候用?

  • ✅ 适合提前定义好,后面反复调用的场景(比如工具函数)
  • ❌ 不适合写在条件语句里(会有 "变量提升" 陷阱,后面会讲)

2.2 更灵活的函数表达式:赋值给变量

语法长这样

javascript 复制代码
const 变量名 = function(参数1, 参数2) { 
  // 函数体 
};

举个生活例子:像 "便签式" 菜谱,随时写在小纸条上用。

javascript 复制代码
// 定义:把函数当作"值"存到变量里
const add = function(a, b) { 
  return a + b; 
};
// 调用:通过变量名调用
console.log(add(2, 3)); // 输出:5

隐藏技能

  • 可以匿名(不用给函数起名),适合临时用一次的逻辑
  • 能放在对象里当 "方法":
javascript 复制代码
const calculator = {
  sum: function(a, b) { // sum是对象的方法
    return a + b;
  }
};
console.log(calculator.sum(10, 20)); // 输出:30

2.3 极简箭头函数:ES6 语法糖

语法长这样

javascript 复制代码
const 变量名 = (参数1, 参数2) => { 
  // 函数体 
  return 结果; 
};

简化规则

情况 正常写法 箭头简化写法
无参数 () => {} 直接() => {}
单参数 (a) => {} 可省略括号 a => {}
单语句且有返回值 (a,b) => { return a+b; } 直接(a,b) => a+b

举个例子

dart 复制代码
// 计算数组每个数的平方
const numbers = [1, 2, 3];
const squares = numbers.map(function(num) { // 传统函数表达式
  return num * num;
});
// 用箭头函数简化后:
const squares = numbers.map(num => num * num); // 一行搞定!

注意陷阱

  • ❌ 没有自己的this(会继承外层作用域的this,适合处理数组时用)
  • ❌ 不能用作构造函数(不能用new关键字创建对象)

2.4 进阶玩法:构造函数(用 new 创建对象)

语法长这样

javascript 复制代码
function 构造函数名(参数1, 参数2) { 
  this.属性名 = 参数1; // 定义对象属性
  this.方法名 = function() { ... }; // 定义对象方法
}

举个例子:像 "模板工厂",批量生产同类对象。

javascript 复制代码
// 定义"人类"模板
function Person(name, age) { 
  this.name = name; 
  this.age = age; 
  this.sayHi = function() { 
    console.log(`我是${this.name},今年${this.age}岁`);
  };
}
// 生产具体对象
const tom = new Person("Tom", 20); 
const lisa = new Person("Lisa", 18); 
tom.sayHi(); // 输出:我是Tom,今年20岁

关键区别

  • ✅ 函数名首字母大写(约定俗成,方便区分)
  • ✅ 必须用new调用(否则this会指向全局对象,导致 bug)

三、终极对比表:到底该选哪一种?

定义方式 语法复杂度 能否复用 this 指向 适用场景 经典错误提醒
函数声明 ★☆☆☆☆ ✅ 高 调用时决定(默认全局) 全局工具函数 别在 if 里定义!会变量提升
函数表达式 ★★☆☆☆ ✅ 中 取决于所在对象 对象方法、回调函数 别忘了分号结尾!
箭头函数 ★★★☆☆ ✅ 中 继承外层作用域 数组遍历、简单逻辑 别用在需要自己 this 的地方!
构造函数 ★★★★☆ ✅ 高 新创建的对象 批量生成对象 一定要用 new!

四、新手常见误区 + 避坑指南

4.1 变量提升是什么鬼?

现象:函数声明可以在定义前调用,而函数表达式不行:

scss 复制代码
// 函数声明:可以"先调用后定义"
sayHi(); // 输出:你好!
function sayHi() { console.log("你好!"); }
// 函数表达式:先调用会报错
sayHello(); // 报错:sayHello is not a function
const sayHello = function() { console.log("哈喽!"); };

原理:函数声明会被 JavaScript 引擎 "提前读取",而函数表达式是赋值操作,必须先赋值再用。

4.2 箭头函数的 this 为什么总出错?

看下面这个例子:

javascript 复制代码
const obj = {
  name: "小明",
  // 错误示范:用箭头函数定义方法
  sayName: () => { 
    console.log(this.name); // 输出:undefined(因为箭头函数的this是外层全局作用域)
  }
};
obj.sayName();
// 正确示范:用传统函数表达式
const obj = {
  name: "小明",
  sayName: function() { 
    console.log(this.name); // 输出:小明(this指向obj对象)
  }
};
obj.sayName();

记住:箭头函数没有自己的this,它的this是定义时所在的作用域(通常是外层函数或全局),而不是调用时的对象。

五、实战练习:用 4 种方式实现同一功能

需求:写一个函数,接收两个数,返回它们的乘积。

5.1 函数声明版

javascript 复制代码
function multiply(a, b) {
  return a * b;
}
console.log(multiply(3, 4)); // 12

5.2 函数表达式版

javascript 复制代码
const multiply = function(a, b) {
  return a * b;
};
console.log(multiply(3, 4)); // 12

5.3 箭头函数版

css 复制代码
const multiply = (a, b) => a * b;
console.log(multiply(3, 4)); // 12

5.4 构造函数版(虽然不太适合,但演示用)

javascript 复制代码
function Calculator() {
  this.multiply = function(a, b) {
    return a * b;
  };
}
const calc = new Calculator();
console.log(calc.multiply(3, 4)); // 12

六、总结:一张图记住所有知识点

最后送你一句口诀

简单逻辑用箭头,对象方法表达式;

重复调用声明式,批量对象构造器。

遇到 this 别慌神,箭头继承外层去,

传统函数看调用,谁调 this 就指谁!

下次遇到函数定义题,按照 "需求→场景→选类型" 三步法,轻松搞定~ 如果你在练习中遇到具体问题,欢迎留言讨论!

相关推荐
涵信7 分钟前
第十节:性能优化高频题-虚拟DOM与Diff算法优化
javascript·vue.js·性能优化
谈不譚网安8 分钟前
CSRF请求伪造
前端·网络安全·csrf
TT模板13 分钟前
苹果cmsV10主题 MXonePro二开优化修复开源版
前端·html5
拖孩14 分钟前
【Nova UI】十一、组件库中 Icon 组件的测试、使用与全局注册全攻略
前端·javascript·vue.js·ui·sass
去伪存真20 分钟前
不用动脑,手把手跟着我做,就能掌握Gitlab+Jenkins提交代码自动构部署
前端·jenkins
丘山子37 分钟前
如何在 1000 亿级数据规模下实现高效的去重统计?
后端·面试·架构
天天扭码1 小时前
深入解析 JavaScript 中的每一类函数:从语法到对比,全面掌握适用场景
前端·javascript·面试
uhakadotcom1 小时前
Lovable:用AI轻松打造完整应用,零基础也能快速开发
后端·面试·架构
小希爸爸1 小时前
4、中医基础入门和养生
前端·后端
kooboo china.1 小时前
Tailwind CSS 实战:基于 Kooboo 构建企业官网页面(一)
前端·css·编辑器