js函数(function )全方位解析

JavaScript 中的函数是编程的核心概念之一,涉及分类、参数的使用以及高级函数的概念。以下是对这些内容的全方位解析。

1. 函数的分类

在 JavaScript 中,函数可以根据不同的标准进行分类:

1.1 按照定义方式
  • 函数声明

    function greet() {
      console.log('Hello!');
    }
    
  • 函数表达式

    const greet = function() {
      console.log('Hello!');
    };
    
  • 箭头函数(ES6):

    const greet = () => {
      console.log('Hello!');
    };
    
1.2 按照用途
  • 普通函数:用于执行特定的任务。
  • 回调函数:作为参数传递给其他函数,在特定事件发生时被调用。
  • 构造函数:通过 new 关键字创建对象的函数,通常以大写字母开头。
  • 生成器函数:使用 function* 声明,可以在执行过程中暂停与恢复。

2. 函数的参数

在 JavaScript 中,函数的参数非常灵活,可以使用多种方式处理:

2.1 普通参数
function add(a, b) {
  return a + b;
}
2.2 默认参数(ES6)
function multiply(a, b = 1) {
  return a * b;
}
2.3 剩余参数(Rest Parameters)

使用 ... 语法,可以将未定义的参数组合成数组。

function sum(...args) {
  return args.reduce((total, num) => total + num, 0);
}
2.4 结构赋值

可以在函数参数中直接对对象或数组进行结构赋值。

function display({ name, age }) {
  console.log(`Name: ${name}, Age: ${age}`);
}

display({ name: 'Alice', age: 25 });

3. 高级函数

高级函数是指能够操作其他函数的函数。主要包括:

3.1 函数作为参数

函数可以作为参数传递给其他函数。

function executeCallback(callback) {
  callback();
}

executeCallback(() => console.log('Callback executed!'));
3.2 函数作为返回值

一个函数可以返回另一个函数。

function outerFunction() {
  return function innerFunction() {
    console.log('Inner function executed!');
  };
}

const inner = outerFunction();
inner();
3.3 闭包

闭包是访问自由变量的函数,能够保持其外部函数的作用域。

function makeCounter() {
  let count = 0;
  return function() {
    count++;
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); 
console.log(counter()); 

4. 高级概念

4.1 记忆化(Memoization)

记忆化是一种优化技术,用于缓存函数的返回值,以提高性能。

function memoize(fn) {
  const cache = {};
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache[key]) {
      return cache[key];
    }
    const result = fn(...args);
    cache[key] = result;
    return result;
  };
}

const fibonacci = memoize(n => {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
});
4.2 高阶函数

高阶函数是指接受函数作为参数或返回函数的函数。它们可以实现函数组合、函数回调等功能。

function higherOrderFunction(fn) {
  return function(arg) {
    console.log('Before calling the function');
    fn(arg);
    console.log('After calling the function');
  };
}

const wrappedFunc = higherOrderFunction(console.log);
wrappedFunc('Hello, World!');

4.3. 纯函数

定义

纯函数是一种没有副作用的函数,即:

  • 对相同的输入,始终返回相同的输出。
  • 不会依赖或修改外部状态,即不修改外部变量或数据。
特点
  • 可预测性:由于输出仅依赖输入,测试和调试相对简单。
  • 易于优化:纯函数容易进行某些优化(如缓存、并行处理)。
示例
function add(a, b) {
  return a + b; 
}

let x = 5;
function increment() {
  x++; 
  return x;
}

4.4. 函数提升

定义

函数提升是指 JavaScript 在执行代码之前,会把函数声明提升到作用域顶部。不同于函数表达式,函数声明会在代码运行之前被处理。

特点
  • 提升适用于函数声明,但不适用于函数表达式。
  • 提升的顺序由代码块的顺序决定。
示例
console.log(greet()); 
function greet() {
  return 'Hello';
}


var sayHi = function() {
  return 'Hi';
};

4.5. 使用剩余参数注意的问题

剩余参数(Rest Parameters)

使用 ... 操作符收集函数的剩余参数,形成一个数组。

注意事项
  • 剩余参数必须是函数参数列表中的最后一个参数。
  • 不能与其他参数混用,如命名参数后面再使用剩余参数。
示例
function sum(...args) {
  return args.reduce((acc, curr) => acc + curr, 0);
}


4.6. 函数调用时应注意的问题

传参方式
  • 确保传入的参数类型与函数预期相符。可以通过检查参数类型来增强健壮性。
function multiply(a, b) {
  if (typeof a !== 'number' || typeof b !== 'number') {
    throw new Error('Both arguments must be numbers.');
  }
  return a * b;
}
this 绑定
  • 注意在不同上下文中 this 的绑定。常见的问题是使用常规函数和箭头函数时 this 的行为不同。
const obj = {
  value: 42,
  getValue: function() {
    return this.value; 
  },
  getArrowValue: () => this.value 
};
处理异常
  • 在进行函数调用时,可以使用 try...catch 块来处理可能的异常,保持应用的健壮性。
try {
  console.log(multiply(2, 'string')); 
} catch (error) {
  console.error(error.message); 
}
递归调用
  • 注意递归调用的基准条件,避免导致栈溢出。
function factorial(n) {
  if (n <= 1) return 1; 
  return n * factorial(n - 1);
}

5. 普通函数和递归函数的异同

相同点
  1. 函数结构:二者都是函数,都可以接受参数并返回结果。
  2. 使用范围:可以在相同的场景中使用,都是编程解决问题的工具。
  3. 暴露接口:都可以作为模块或类的方法被外部调用。
不同点
特点 普通函数 递归函数
自我调用 不调用自身 直接调用自身
解决方法 通常采用迭代或顺序处理 通过分解问题为子问题进行处理
基准条件 不需要基准条件 需要基准条件以终止递归
复杂性 相对简单,易于理解 可能比较复杂,容易出现栈溢出的问题
性能表现 通常性能较稳定 可能受限于调用栈深度,且可能存在性能损耗(尤其是深层递归时)

6. 普通函数和箭头函数的异同

相同点
  1. 函数结构:两者都是函数,可以接受参数并返回结果,能用于定义回调。
  2. 可以作为一等公民:普通函数和箭头函数都可以作为参数传递和返回值。
不同点
特点 普通函数 箭头函数
 this 绑定 动态绑定,取决于调用上下文 静态绑定,继承外部作用域的this 
能否作为构造函数 可以使用 new 关键字 不能使用 new 关键字
 arguments 对象 有自己的 arguments 对象 不支持 arguments 对象
函数提升 声明会被提升,可以在声明之前调用 不会被提升,须在定义后调用
表达式简化 需要完整的语法形式 可以省略大括号及 return 语句
使用场景
  • 普通函数:适合需要自己管理 this 绑定的场景、作为构造函数或者需要使用 arguments 对象的情况。
  • 箭头函数:适合需要保持上下文 this 的场景,常用于回调函数、数组方法(如 mapfilterreduce)等,可以使代码更加简洁和可读。

7. 函数表达式和函数声明的区别

一、函数声明
定义

函数声明是使用 function 关键字声明的函数。

语法
function functionName(parameters) {
  
}
特点
  1. 提升(Hoisting) :函数声明会被提升到其所在作用域的顶部。这意味着可以在函数声明之前调用该函数。
  2. 命名函数:函数声明是命名的,可以在函数体内部使用 arguments 对象。
  3. 定义形式:函数声明具有明确的定义形式。
示例

function greet() {
  console.log("Hello!");
}

greet(); 

二、函数表达式

定义

函数表达式是将一个函数赋值给变量或属性的方式。

语法
const functionName = function(parameters) {
  
};
特点
  1. 无提升:函数表达式不会被提升,必须在定义后才能调用,否则会抛出错误。
  2. 可匿名:函数表达式可以是匿名的,可以没有名称,通常用于立即调用或作为回调。
  3. 可以作为对象的方法:函数表达式可以被赋值为对象的属性。
示例

const greet = function() {
  console.log("Hello!");
};


greet(); 
特点 函数声明 函数表达式
提升(Hoisting) 会被提升,可以在声明之前调用 不会被提升,必须在定义后调用
命名 一般是命名的,支持 arguments 对象 可以是匿名的,不支持 arguments 
作用域 在其定义的作用域处可见 仅能在定义之后的作用域内可见
适用场景 用于定义可重复使用的函数 用于动态创建函数、回调或立即执行的场合

总结

JavaScript 的函数既强大又灵活,支持多种参数的表现形式和高级概念。掌握这些函数的分类、参数处理和高级函数的使用,能够大大提升 JavaScript 编程的能力和代码的可读性。通过练习这些概念,能够更深入理解 JavaScript 的函数特性及其应用。

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21212,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?