JavaScript 函数表达式

本文介绍了JavaScript中的函数表达式,包括其特点如可选的函数名称、在执行阶段创建及不会影响变量对象等,并探讨了函数递归及代码模块化的应用场景。

JavaScript 函数表达式

  JavaScript中创建函数主要有两种方法:函数声明和函数表达式。这两种方式都有不同的适用场景。这篇笔记主要关注的是函数表达式的几大特点以及它的使用场景,下面一一描述。

  主要特点

  • 可选的函数名称

  函数名称是函数声明的必需组成部分,这个函数名称相当于一个变量,新定义的函数会复制给这个变量,以后函数的调用都需要通过这个变量进行。而对于函数表达式来说,函数的名称是可选的,例如下面的例子:

1

2

3

var sub = function(a1,a2){

    return a1-a2;

}

  这个例子中函数表达式没有名称,属于匿名函数表达式。再看下面的例子:

1

2

3

4

5

var sub = function f(a1,a2){

    return a1-a2;

}

console.log(f(5,3));   //错误调用方式

console.log(sub(5,3));   //正确调用方式

  在这个例子中,函数表达式的名称为f,这个名称f实际上变成了函数内部的一个局部变量,并且指代函数对象本身,在函数递归的时候有很大用处,后面会详细讲到。

  • 在执行阶段创建(区别于函数声明)

   这个特点是函数表达式明显区别于函数声明的地方。

  解释器在解析JavaScript代码时对于这两种方式并不是一视同仁的。解释器会首先读取函数声明,并使其在执行任何代码之前可用;而对于函数表达式,则必须等到解释器执行到它所在的代码行,才会被真正解析执行。例如:

1

2

3

4

5

6

7

8

console.log(add(1,2));   //"3"

console.log(sub(5,3));   //"unexpected identifier",报错

function add(a1,a2){

    return a1+a2;

}

var sub = function(a1,a2){

    return a1-a2;

}

  第一条语句完全可以正常执行。对代码求值时,JavaScript引擎在第一遍就会声明函数并通过一个名为函数声明提升的过程将它们放到源代码树的顶部。也就是说在执行环境的创建阶段(函数被调用但还没有开始执行)就会对函数声明进行"hosting"操作。所以,即使声明函数的代码在调用它的代码后面,JavaScript引擎也会把函数声明提升到顶部。但是如果把函数声明更改为函数表达式,就会在执行期间报错。原因在于在执行到函数所在的语句之前,变量sub中并不会包含对函数的引用。也就是说在代码执行阶段,变量sub才会被赋值。除了以上不同,在其它方面函数声明和函数表达式的语法是等价的。

  • 不会影响变量对象

1

2

3

4

5

var sub = function f(a1,a2){

    console.log(typeof f);  //"function"

    return a1-a2;

}

console.log(typeof f);   //"Uncaught ReferenceError: f is not defined(…)"

  通过上面的例子可以看到,函数名称f只能在函数对象内部使用,函数表达式的函数名称并不存在于变量对象中。

  使用场景

  函数表达式的使用场景很多。下面主要描述的是函数递归以及代码模块化方面的应用。

  • 函数递归

  看下面的例子:

1

2

3

4

5

6

7

function factorial(num){

    if(num <= 1){

         return 1;

    }else{

         return num * factorial(num - 1);

    }

}

  这是一个经典的阶乘函数,但是这个例子存在的一个问题是函数名称factorial与函数体紧密耦合在一起,执行下面的语句就会报错:

1

2

3

var anotherFactorial = factorial;

factorial = null;

console.log(anotherFactorial(5));   //"Uncaught TypeError: factorial is not a function"

  报错的原因在于在函数体内部会调用factorial函数,而变量factorial对函数的引用已经被解除所以报错。这种情况的解决方法一般可以使用arguments.callee来解决,arguments.callee始终指向当前的函数,例如:

1

2

3

4

5

6

7

function factorial(num){

    if(num <= 1){

         return 1;

    }else{

         return num * arguments.callee(num - 1);

    }

}

  这样在此执行anotherFactorial函数就可以得到正确结果了。但是在严格模式"strict"下,arguments.callee是不能通过脚本访问的,这是就可以使用函数表达式来解决这个问题了,例如:

1

2

3

4

5

6

7

8

var factorial = (function f(num){

    if(num <= 1){

         return 1;

    }else{

         return num * f(num - 1);

    }

});

console.log(factorial(5));   //"120"

  • 代码模块化

  JavaScript中没有块级作用域,但我们可以使用函数表达式模块化JavaScript代码。模块化代码中可以封装不必让使用者知道的细节,只暴露给使用者相关接口,同时可以避免对全局环境的污染,例如:

1

2

3

4

5

6

7

8

9

10

11

12

13

var person = (function(){

    var _name = "";

    return{

        getName:function(){

             return _name;

        },

        setName:function(newname){

             _name = newname;

        }

    };

}());

person.setName("John");

person.getName();   //"John"

  这个例子中创建了一个匿名函数表达式,这个函数表达式中包含了模块自身的私有变量和函数;这个函数表达式的执行结果返回一个对象,对象中包含了模块暴露给使用者的公共接口。代码模块化的具体形式还有很多,例如在一些常用的JavaScript库中通常都会使用类似下面例子的立即执行函数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

(function(){

    var _name = "";

    var root = this;

    var person = {

        getName: function(){

            return _name;

        },

        setName: function(newname){

            _name = newname;

        }

    };

    root.person = person;

}.call(this));

person.setName("John");

person.getName();   //"John"

  这种方式直接将包含模块公共接口的对象作为全局对象的一个属性,这样在其它地方直接可以使用全局对象的这个属性来使用这个模块了。

  这篇笔记只包含了JavaScript中函数表达式的一部分内容,可能存在不准确或错误的地方,希望能够指出!

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值