JavaScript函数

函数

1.函数介绍

将一系列代码进行封装,并实现一定的功能,实现代码复用。

JavaScript定义函数的格式

function 函数名称(形参列表)(){}; //直接声明,若没有函数名称,则为匿名函数
var foo=function(形参列表){};  //函数表达式

函数的作用

功能封装,直接调用,提高代码复用率

2.函数声明提升

函数的声明和var变量声明类似,都会进行提升,提升到代码的最前边,即可以在声明函数前调用函数,函数声明提升优先于变量声明提升

var sum=add(2,3);//函数声明提升,sum=5
function add(a,b){
  var result = a + b;
  return result;//返回值
}
var total = add(1,2) //total=3
3.函数内部属性

在函数内部才能访问的属性,通过this也可在函数外部使用

arguments

是一个接收传入函数的所有参数的类数组对象,拥有length属性,但没有数组特有的属性

function add(a,b){
  var result = a + b;
  return result;//返回值
}
var total = add(1,2,3,4,5)//  total=3
/*
arguments={
	“0”:1,
	“1”:2,
	“2”:3,
	"3":4,
	"4":5
};
*/

其中callee属性是arguments对象的成员,callee指向正在被执行的function对象

//递归实现1~n的和
function sum(n){
	if(n==1)
        return 1;
	else{
        //return n+arguments.callee(n-1)
        //即arguments.callee(n-1) == sum(n-1)
        return n+sum(n-1);
    }   
}
this

this表示对当前对象的引用,会随着执行环境的不同而变化

  1. 在方法中,this指向该方法所属的对象

  2. 在全局使用时,this指向全局对象

  3. 在函数中使用,this指向全局对象

  4. 在事件中使用,this指向接收事件的元素

    <button onclick="this.style.display='none'"> 点我后我就消失了 </button>
    
  5. 可以通过call、apply、bind改变this的指向

4.立即执行函数(IIFE)

​ 表示立即调用的函数表达式,即声明函数的同时调用该函数

作用:

  1. 只执行一次的函数
  2. 函数中的变量只作用于函数作用域中,不会泄漏成全局变量

IIFE的格式:

//1.对返回结果不进行处理
(function(形参){
	//代码
})(实参);
 
//2.返回的是一个布尔值,然后进行取反
!function(形参){
	//代码
    return (true/false);
}(实参)
    
//3.返回值若为数字,返回原来的结果,非数字返回NaN
+function(形参){
	//代码
}(实参)
    
//4.返回值若为数字,返回原来结果的相反值,非数字返回NaN
-function(形参){
	//代码
}(实参)
    
//5.返回值若为数字,返回原来结果的相反值-1,非数字返回-1
~function(形参){
	//代码
}(实参)
    
//6.返回的结果是undefined
void function(形参){
	//代码
}(实参)

为什么需要IIFE?

​ 为了弥补JS(ES5)在作用域的缺陷,在ES6前JS只有全局作用域函数作用域(在ES6后有了块级作用域),因此IIFE主要是实现作用域的隔离。

5.作用域

全局作用域:函数之外声明的变量,会成为全局变量,函数内部可以访问

函数作用域:函数中声明的变量,会成为函数的局部变量,函数外部不能访问

作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突

经典案例
var a = 10;

function foo() {
  // 当函数内部有变量a时,会产生局部作用域,外界全局作用域中的a不会对函数内部造成影响
  // 如果把函数内部的变量a注释掉,函数内部的a输出的就是全局作用域中的a
  
  //此时变量a声明提升,因此输出undefined
  console.log(a); //undefined
  var a = 100;
  console.log(a); // 100

  function fn() {
      //同上
    console.log(a); //undefined
    var a = 200;
    console.log(a); // 200
  }
  fn()
}
foo()
作用域链

自由变量

自由变量就是在全局中声明了该变量,并且在函数内部调用,但是在函数内部没有声明该变量

作用域链

层级关系,在函数内没有该变量就会向上一层寻找。
在这里插入图片描述

综合案例

作用域链-闭包-经典面试题

var a = 10
function fn() {
  var b = 20
  function bar() {
    console.log(a + b) //30
  }
  return bar
}
var x = fn(),b = 200; // 执行fn() 返回的是bar
x() //执行x,就是执行bar函数
6.函数调用
调用方式
  • 函数名(实参列表);

  • 函数名.call(执行环境对象,实参列表);

  • 函数名.apply(执行环境对象,实参列表数组);

  • 函数名.bind(执行环境对象)(实参列表);

总结:call和apply都是改变上下文中的this指向并立即执行这个函数,bind方法需要等函数进行调用时才执行,并且参数可以在执行是添加,也可以在调用bind方法时添加。

7.函数的应用
1.作为回调函数

即先执行完主函数,再执行回调函数

作用:

回调函数主要用作耗时操作中,如ajax请求、处理文件

调用回调函数可以让主函数不用等待这些耗时操作

//定义主函数,回调函数作为参数
function A(callback) {
  callback();
  console.log('我是主函数');
}
//定义回调函数
function B() {
  // 模仿延时操作
  setTimeout(() => {
    console.log('我是回调函数');
  }, 3000);
}
//调用主函数,将函数B传进去
A(B);
/*
输出:
	我是主函数
    我是回调函数
*/
2.作为返回值

将一个函数作为另一个函数的返回值

var a = 10
function fn() {
  var b = 20
  function bar() {
    console.log(a + b) //30
  }
  return bar;   //此时返回的就是bar函数
}
var x = fn(), // 执行fn() 返回的是bar
b = 200
x() //执行x,就是执行bar函数
8.闭包

闭包就是有权访问另一个函数作用域中的变量的函数

MDN 上面这么说闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成

生成闭包的条件

  • 函数嵌套函数

  • 内部函数引用了外部函数中的数据(属性、函数)

  • 参数和变量不会被回收

闭包的作用:

  1. 读取函数内部的变量
  2. 变量的值始终保持在内存中,不会被垃圾回收机制回收

闭包的缺点:

  • 变量保存在内存中,内存消耗很大
  • 不恰当的使用闭包可能会造成内存泄漏,所以不能滥用闭包

解决办法:

在退出函数之前,将不使用的局部变量全部删除,置空

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值