浅谈JavaScript函数

86 阅读5分钟

函数的返回值

  • 在函数中使用return关键字来返回结果
  • 一旦在函数中执行return操作,那么当前函数会终止
  • 如果函数中没有使用 return语句 ,那么函数有默认的返回值:undefined
  • 如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined;

函数声明 vs 函数表达式

  • 函数声明:在主代码流中声明为单独的语句的函数。
  • 函数表达式:在一个表达式中或另一个语法结构中创建的函数。

函数表达式是在代码执行到达时被创建,并且仅从那一刻起可用; 函数声明则可以在声明的上面调用

JavaScript头等函数

头等函数(first-class function;第一级函数)是指在程序设计语言中,函数被当作头等公民。

这意味着,函数可以作为别的函数的参数、函数的返回值,赋值给变量或存储在数据结构中;对作为头等公民的编程方式,称之为函数式编程

JavaScript就是符合函数式编程的语言

回调函数(Callback Function)

回调函数通常作为参数传递给其他函数,以便在特定事件发生时被调用。回调函数常用于异步编程,以处理异步操作的结果。例如,当Ajax请求完成时,可以使用回调函数来处理返回的数据。

高阶函数

高阶函数是指可以接受函数作为参数,或者返回函数作为结果的函数。

高阶函数必须至少满足两个条件之一:

  • 接受一个或多个函数作为输入
  • 返回一个函数;

匿名(anonymous)函数的理解

如果在传入一个函数时,我们没有指定这个函数的名词或者通过函数表达式指定函数对应的变量,那么这个函数称之为匿名 函数

立即执行函数

//立即执行函数的两种写法

//第一种:用括号把整个函数定义和调用包裹起来
(function(){
 //function body
}())

//第二种:用括号把函数定义包裹起来,后面再加括号
(function (){
 //function body
})()

上边的两种写法,就是立即执行函数的两种写法,都是以圆括号开头,JS引擎会认为后面跟的是表达式,而不是一个函数定义语句,所以就避免了错误,这就叫做"立即调用的函数表达式"

立即执行函数一般也写成匿名函数,匿名函数写法为function(){/…/},所谓匿名函数,就是使用function关键字声明一个函数,但未给函数命名,倘若需要传值,直接将参数写到括号内即可。

将它赋予一个变量则创建函数表达式,赋予一个事件则成为事件处理程序等。但是需要注意的是匿名函数不能单独使用,否则会js语法报错,至少要用()包裹起来。

立即执行函数主要有以下特点:

  • 代码逻辑在页面加载完成之后,不得不执行一些设置工作,比如时间处理器,创建对象等等。
  • 所有的这些工作只需要执行一次,比如只需要显示一个时间。
  • 但是这些代码也需要一些临时的变量,但是初始化过程结束之后,就再也不会被用到,如果将这些变量作为全局变量,不是一个好的设计,可以用立即执行函数——去将所有的代码包裹在它的局部作用域中,不会让任何变量泄露成全局变量,如下代码:
当前时间:<span id="today"></span>
<script>
	(function(){
		var todaydom=document.getElementById("today");
		var days=["星期日","星期一","星期二","星期三","星期四","星期五","星期六"1; 
		var today=new Date( );
		var year=today.getFullYear(); 
		var month=today.getMonth()+1; 
		var date=today.getDate(); 
		var day=today.getDay();
		var msg=year+"年"+month+"月"+date+"日"+days [day]; 
		todaydom.innerHTML=msg;
	})()
</script>

比如上面的代码,如果没有被包裹在立即执行函数中,那么临时变量todaydom,days,today,year,month,date,day,msg都将成为全局变量(初始化代码遗留的产物)。用立即执行函数之后,这些变量都不会在全局变量中存在,以后也不会其他地方使用,有效的避免了污染全局变量。

总结👇🏻:立即执行函数会形成一个单独的作用域,可以封装一些临时变量或者局部变量,避免污染全局变量。

var result = (function(){
	var res = 2+2;
	return function( ) { return res;
	})()
console.log(result());//4

上例中立即执行函数的返回值被赋值给了一个变量result,这个函数简单的返回了res的值,这个值事先被计算并被存储在立即执行行数的闭包中。

立即执行函数有哪些作用?

  • 改变变量的作用域(创建一个独立的作用域)
<body>
    <ul id="list">
        <li>公司简介</li>
        <li>联系我们</li>
        <li>营销网络</li>
    </ul>
    <script>
      var list = document.getElementById("list");
      var li = list.children;
      for(var i = 0 ;i<li.length;i++){
       (function(j){
            li[j].onclick = function(){
              alert(j);
          })(i); 把实参i赋值给形参j
        }
      }
     </script>  
</body>

改变变量i的作用域,把全局变量i以参数的形式传递到立即执行函数中,在立即执行函数中定义变量i的形参变量j,变量j就是在立即执行函数的作用域中。(给每个li创建了一个作用域块,点击的时候寻找自由变量j,在立即执行块中找到)

  •  封装临时变量
当前时间:<span id="today"></span>
<script>
	(function(){
		var todaydom = document.getElementById("today");
		var days = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"1; 
		var today = new Date( );
		var year = today.getFullYear(); 
		var month = today.getMonth()+1; 
		var date = today.getDate(); 
		var day = today.getDay();
		var msg = year+"年"+month+"月"+date+"日"+days [day]; 
		todaydom.innerHTML=msg;
	})()
</script>

在上面的代码中,可以封装临时变量,避免全局变量的污染。也可以返回一个在全局中需要的变量(用return实现)

部分知识内容参考自 JavaScript进阶(二十三):立即执行函数(匿名函数)( ( ) { } ( ) )含义解析_No Silver Bullet的博客-CSDN博客