函数声明

使用function的函数声明比函数表达式优先提升
变量对象的创建过程中,函数声明比变量声明有更为优先的执行顺序
无论在什么位置声明了函数,都可以在同一个执行上下文中直接使用

函数表达式

也叫匿名函数
函数表达式使用var/let/const声明,我们在确认他是否可以正确使用时,必须依照var/let/const的规则判断,即
变量声明
使用var进行变量声明,进行了两步操作

函数声明和函数表达式主要有以下区别:

一、语法形式

  1. 函数声明:
    • 使用 function 关键字,后跟函数名,再加上括号和花括号包裹的函数体。
    • 例如:
      1
      2
      3
      function add(a, b) {
      return a + b;
      }
  2. 函数表达式:
    • 将一个匿名函数赋值给一个变量。
    • 例如:
      1
      2
      3
      const subtract = function(a, b) {
      return a - b;
      };

二、提升(Hoisting)特性

函数声明会在代码执行前被提升到其所在作用域的顶部,这意味着可以在函数声明之前调用该函数。而函数表达式只有在其所在的语句被执行到的时候才会被创建,不能在其定义之前被调用。

例如:

1
2
3
4
5
console.log(add(2, 3)); // 输出 5,函数声明可以在声明之前调用
console.log(subtract(5, 2)); // 报错,因为函数表达式在定义之前不能调用
const subtract = function(a, b) {
return a - b;
};

三、命名方式

函数声明必须有一个名称,而函数表达式可以是匿名的(没有名称),也可以是具名的(有名称),但这个名称只在函数内部可见。

例如:

1
2
3
4
5
6
7
8
function multiply(a, b) {
return a * b;
}
const divide = function namedDivide(a, b) {
return a / b;
};
console.log(multiply(4, 2)); // 输出 8
console.log(divide(8, 2)); // 输出 4,在函数内部可以使用 namedDivide 这个名称进行递归等操作,但在外部只能通过 divide 来调用
1
2
3
4
5
//变量声明
var a = 20;
//实际执行顺序
var a = undefined;//变量声明,初始值undefined,变量提升,提升l顺序次于function声明
a = 20;//变量赋值,该操作不会提升

同样道理,当我们使用变量声明的方式声明函数时一函数表达式。函数表达的提升方式与变量声明一致

1
2
3
4
5
6
7
8
9
10
11
fn();//报错
var fn=function (){
console.log('function');
}
//上述例子执行顺序为
var fn=undefined;//变量声明提升
fn();//执行报错
fn = function () {
//赋值操作,此时将后边函数的引用赋值给f
console.log('function')
}

因此,由于声明方式的不同,导致函数声明与函数表达式在使用上的一些差异需要注意,除此之外,这两种形式的函致在使用上并无不同

匿名函数

没有被显示进行赋值操作的函数。使用场景一多作为一个参数传入另一个函数中
函数自执行,其实是匿名函数的一种应用

在 JavaScript 中,匿名函数是没有名称的函数表达式。以下是定义和使用匿名函数的方法:

一、定义匿名函数

  1. 作为变量的值
    1
    2
    3
    const myFunction = function() {
    console.log('这是一个匿名函数作为变量的值。');
    };
  2. 作为立即执行函数表达式(IIFE)
    1
    2
    3
    (function() {
    console.log('这是一个立即执行的匿名函数。');
    })();

二、使用匿名函数

  1. 作为回调函数
    1
    2
    3
    4
    5
    6
    7
    8
    function doSomething(callback) {
    console.log('正在执行一些操作...');
    callback();
    }

    doSomething(function() {
    console.log('这是作为回调函数的匿名函数。');
    });
  2. 在数组方法中使用
    1
    2
    3
    4
    const numbers = [1, 2, 3, 4, 5];
    numbers.forEach(function(number) {
    console.log(number);
    });

回调函数

匿名函数传入另一个函数之后,最终在另一个函数中执行,因此我们也常常称这个匿名函数为回调函数

高阶函数

一个函数接收另一个函数作为参数或返回另一个函数
1.map
2.reduce
参数:两个参数,一个为回调函数,另一个初始值。回调函数中四个默认参数,依次为积累值、当前值、当前索引
和整个数组
1.filter返回新数组
2.sort

以下是使用这些高阶函数的 JavaScript 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const numbers = [1, 2, 3, 4, 5];

// 使用 map
const mappedNumbers = numbers.map((num) => num * 2);
console.log(mappedNumbers); // [2, 4, 6, 8, 10]

// 使用 reduce
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 15

// 使用 filter
const filteredNumbers = numbers.filter((num) => num % 2 === 0);
console.log(filteredNumbers); // [2, 4]

// 使用 sort
const sortedNumbers = numbers.sort((a, b) => a - b);
console.log(sortedNumbers); // [1, 2, 3, 4, 5]

在这个例子中,首先定义了一个数组numbers。然后分别使用map对数组中的每个元素进行乘以 2 的操作,使用reduce计算数组元素的总和,使用filter筛选出偶数元素,使用sort对数组进行升序排序。

普通函数

若是’use strict’,不能将全局对象window作为默认绑定。this=undefined
普通函数:定义时this指向函数作用域,但定时器之后执行函数时,this指向window
普通函数的this一调用时所在的对象
函数声明、函数表达式
1.函数声明式:function functionName()}
2.函数表达式:let name=function()0

以下是关于普通函数以及严格模式下相关行为的 JavaScript 代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 非严格模式下的函数声明
function declaredFunction() {
console.log(this);
}
declaredFunction();

// 非严格模式下的函数表达式
let expressionFunction = function() {
console.log(this);
};
expressionFunction();

// 定时器中的非严格模式函数
setTimeout(function() {
console.log(this);
}, 1000);

// 严格模式下的函数声明
(function strictDeclaredFunction() {
'use strict';
console.log(this);
})();

// 严格模式下的函数表达式
let strictExpressionFunction = function() {
'use strict';
console.log(this);
};
strictExpressionFunction();

// 定时器中的严格模式函数
setTimeout(function() {
'use strict';
console.log(this);
}, 2000);

在这个例子中,可以观察到非严格模式下普通函数在不同场景下的 this 指向,以及严格模式对 this 指向的影响。