前端入门09 -- JavaScript之函数,作用域链,闭包

函数

  • 函数也是一个对象;
  • 函数:把一个或者多功能通过函数的方式封装起来,对外只提供一个简单的函数接口;
  • 声明定义函数的三种方式:
    • 利用函数关键字function 自定义函数;
    • 函数表达式,用一个变量接收函数表达式;
    • 箭头函数,用一个变量接收定义的箭头函数;
    
    

函数的参数

  • 行参:形式上的参数,函数定义的时候传递的参数 当前并不知道是什么;
  • 实参:实际上的参数,函数调用的时候传递的参数 实参是传递给行参的;
  • 函数的参数可以有,也可以没有个数不限;



    
    
    
    Document
    




  • 函数形参实参的个数匹配问题:
    • 如果实参的个数和形参的个数一致,则正常输出结果;
    • 如果实参的个数多于形参的个数,会取到形参的个数;
    • 如果实参的个数小于形参的个数,多于的形参定义为undefined,最终的结果就是NaN;



    
    
    
    Document
    




箭头函数的参数与参数默认值
  • 箭头函数中只有一个参数时,可以省略();
  • 箭头函数中代码只有一行时,可以省略{};
  • 参数没有传入实参时,参数默认值才会生效;
  
Object对象作为函数参数
  • Object对象可以作为函数的参数;
  
  • Object对象字面量作为函数参数默认值,函数多次调用,会多次创建新的Object对象字面量;
  • 自定义Object对象作为函数参数默认值,函数多次调用,都使用的同一个自定义Object对象;
  
函数作为函数参数
  • 自定义函数,匿名函数表达式,箭头函数作为函数的参数;
  
arguments的使用
  • 当我们不确定有多少个参数传递的时候,可以用arguments来获取,在JavaScript中,arguments实际上它是 当前函数的一个内置对象,所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参
  • arguments展示形式是一个伪数组,因此可以遍历,伪数组具有以下特点:
    • 具有length属性;
    • 按索引方式储存数据;
    • 不具有数组的push,pop等方法;
    
函数返回值
  • 函数的返回值:只要函数遇到return 就把后面的结果 返回给函数的调用者,且终止之后的代码执行,且只能返回一个值,是没有返回值类型的;
  • return什么都不返回 或者 不写return,那么函数的返回值为undefined;
    
    
  • 箭头函数只有一行代码,且有返回值,可省略return关键字 和 {};
  • 箭头函数只有一行代码,且返回值为Object对象字面量,那么需要加上(Object对象字面量);
  

JavaScript作用域

  • 全局作用域:整个script标签 或者是一个单独的js文件;
  • 局部作用域:存在两种分别为块级作用域和函数作用域;
    • 块级作用域:在代码块执行时创建,在代码块执行完毕时销毁;
    • 函数作用域:在函数调用时创建,在函数调用完成时销毁;
  • 全局变量:在全局作用域中的变量,注意在函数内部 没有声明直接赋值的变量 也属于全局变量,全局变量只有在浏览器关闭的时候才会被销毁,比较占内存资源;
  • 局部变量:在局部作用域中的变量,当函数执行完成时就会被销毁,比较节约内存资源;
    
  • 作用域链:内部函数访问外部函数变量,JS解释器会优先在当前对象中寻找目标变量,若找到直接使用,若没有找到,则去上一层作用域中去寻找,依次类推,若找到全局作用域都没有找到目标变量,就会报错xxx is not defined,在作用域中寻找目标变量,遵循就近原则
  

JavaScript预解析

  • JavaScript代码是由浏览器中的JavaScript解析器来执行的,JavaScript解析器在运行JavaScript代码的时候分为两个步骤,分别为:预解析代码执行
  • 预解析:js引擎会将js里面所有的var和function 提升到当前作用域的最前面
  • 代码执行:按照代码书写的顺序从上到下依次执行;
  • 变量var的提升:将所有变量var声明提升到当前作用域的最前面,不会提升赋值操作
  • 函数的提升:将所有函数声明(定义)提升到当前作用域的最前面,不调用函数;
  • 变量let的提升:会将所有变量let声明提升到当前作用域的最前面,但是在赋值之前解释器禁止对该变量的访问;
  
    
  • 案例一:
    
  • 案例二:
    

立即执行函数

  • 在开发中应该尽量减少直接在全局作用域中编写代码,尽量在局部作用域中编写代码;
  • 立即执行函数:(function(){})(),是一个匿名函数,直接执行,且只会执行一次;
  
  • 箭头函数没有自己的this,内部打印的this是由外层作用域决定的,等于外层作用域的this;
  • 箭头函数的this和它的调用方式无关;

高阶函数

  • 高阶函数:若一个函数的参数或者返回值为函数,那么这个函数就是高阶函数;
  • 将函数作为参数,就意味着可以对另一个函数动态的传递代码;
  

闭包

  • 闭包:能访问到外部函数作用域中变量的函数;
  • 构成闭包的必要条件:
    • 存在函数的嵌套;
    • 内部函数要引用外部函数的变量;
    • 内部函数要作为返回值;
  
  • 函数的外层作用域(词法作用域),在函数创建时就已经确定了;
  • 闭包的实现原理就是利用了词法作用域;
  
  • 闭包的生命周期:
    • 闭包在外部函数调用时产生,外部函数每次调用都会产生一个全新的闭包;
    • 闭包在内部函数回收时销毁;
  • 闭包的注意事项:
    • 闭包住要用来隐藏一些不希望外部访问的内容,这就意味着闭包需要占用一定的内存空间;
    • 相比较于类Class来说,闭包比较浪费内存空间,因为类可以使用原型而闭包不可以;
  

你可能感兴趣的:(前端入门09 -- JavaScript之函数,作用域链,闭包)