美文网首页
函数与作用域

函数与作用域

作者: akena | 来源:发表于2017-12-17 22:59 被阅读0次
函数声明和函数表达式
  • 函数声明
    function fn() {}
    
    • 必须有函数名
    • 函数可以在任意地方调用
  • 函数表达式
    var fn = function fn() {}
    
    • function 后函数名可以省略
    • function 后函数名只能在函数内部使用
    • 函数表达式只能在声明之后才能调用
作用域和声明提升
  • 作用域

    • 变量作用域
      • 全局变量拥有全局作用域,局部变量只在函数体内有定义
      • 函数体内,局部变量优先级高于同名的全局变量
    • 函数作用域
      • 块级作用域 概念类似的,JavaScript 使用函数作用域(function scope),即在函数体内声明的所有变量在函数体内可以使用及复用
  • 声明提升

    在代码开始执行之前,解析器会在初始化进程中创建全局变量对象 VO(variable object)VO 中包含全局对象原有属性,全局定义的变量和函数

    • VO 的变化与上下文代码的两个执行阶段有关
      1. 变量初始化,进入执行上下文
      2. 执行代码
    • 在变量初始化阶段,VO 会被以下属性按优先级顺序填充
      1. 函数参数(未传入实参时,初始值为 undefined
      2. 函数声明(存在相同名称的属性时,会完全替换该属性)
      3. 变量声明(初始值为 undefined,存在相同名称的属性时会忽略该声明)
    • 在执行代码阶段,依据以上流程,可得知 JavaScript 声明提升(declaration hoisting)特性的结果,即:
      • 将 JavaScript 函数声明的所有变量添加到执行环境中,并将它们按优先级顺序放到源代码树的顶部,故函数声明提升在变量声明提升之前
        var haha = function() {
          console.log('赋值给变量haha')
        }
      
        function haha() {
          console.log('具名函数haha')
        }
      
        haha();  //赋值给变量haha
      
arguments 对象
  • arguments 对象是所有函数中都可用的局部变量,此对象包含传递给函数的每个参数的条目,示例:
      arguments[0]   //对应第一个参数的条目
      arguments[1]   //类推,第二个
      arguments[2]
    
      arguments[1] = 'new Value';  //参数可被设置
    
  • arguments 对象类似 Array,但不是 Array,除了 length 属性来确定传递参数个数外没有任何 Array 属性
函数的重载
  • Java 和 JavaScript 的对比
    • Java 中,通过方法签名来唯一确定一个方法。方法签名的要素包括:方法名、参数类型、参数顺序和参数个数。若两个方法名称相同,但其他要素不同,编译器便将其视为同名的不同方法,从而导致了重载现象
    • JavaScript 中,函数没有签名,其参数由包含零或多个值的数组来表示,完全靠函数名称唯一确定。当存在相同名称的函数时,则后者会覆盖前者,因而不存在重载
  • JavaScript 模仿函数的重载
      //通过检查传入函数中参数的数量,间接达到重载的目的
      function add(num1, num2) {
        if(arguments.length == 1) {
          console.log(arguments[0] + "input 2nd parameter")
        }
        if(arguments.length == 2) {
          console.log(arguments[0] + arguments[1])
        }
      }
    
立即执行函数表达式 IIFE

IIFE 即声明一个匿名函数并即时调用

  • 两种模式
    • 当圆括号包裹函数时,它会默认将函数作为表达式去解析,而不是函数声明
      (function() { /* code */}());
      
    • 当圆括号出现在匿名函数的末尾想要调用函数时,它会默认将函数当成是函数声明
      (function() { /* code */})();
      
  • 用途
    • 创建一个独立的作用域,避免全局污染
 // 这是一个自执行函数,函数内部执行的是自己,递归调用
 function foo() { foo(); }

 // 这是一个自执行匿名函数,因为它没有函数名
 // 所以如果要递归调用自己的话必须用arguments.callee
 var foo = function() { arguments.callee(); };

 // 这可能也算是个自执行匿名函数,但仅仅是foo标志引用它自身
 // 如果你将foo改变成其它的,你将得到一个used-to-self-execute匿名函数
 var foo = function() { foo(); };

 // 有些人叫它自执行匿名函数,尽管它没有执行自己,只是立即执行而已
 (function(){ /* code */ }());

 // 给函数表达式添加了标志名称,可以方便debug
 // 但是一旦添加了标志名称,这个函数就不再是匿名的了
 (function foo(){ /* code */ }());

 // 立即执行函数也可以自执行,不过不常用罢了
 (function(){ arguments.callee(); }());
 (function foo(){ foo(); }());
递归求n!
function fn(i) {
  if(i < 2) {
    return 1
  }else {
    return i*fn(i-1)
  }
}

//简写
function fn(i) {
  return i<2?1:i*fn(i-1)
}

refer to 变量对象 | cnblogs立即执行函数表达式(IIFE) | segmentfault立即执行函数 | 每日一题

相关文章

  • 执行上下文、作用域链、this、闭包

    javascript 执行的是词法作用域,即静态作用域。与之相对的是动态作用域。 静态作用域:函数的作用域在函数定...

  • 作用域和作用域链

    作用域和作用域链 作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在Java...

  • 作用域

    何为作用域 任何编程语言都有作用域的概念,简单来说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可...

  • JavaScript中的作用域和作用域链(一)

    作用域 1.作用域的概念: 变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。 2.全局作用域与...

  • JavaScript静态作用域解析

    静态作用域与动态作用域 因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。而与...

  • 词法作用域 - 2023-02-09

    静态作用域与动态作用域 因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。而与...

  • JS基础知识(2) -- 作用域和作用域链

    作用域 作用域就是变量与函数的可访问范围 全局作用域 函数作用域 ES6块级作用域 ES5没有块级作用域,ES6有...

  • 作用域链

    一、作用域 定义:作用域就是变量与函数的可访问范围。作用域控制着变量与函数的可见性和生命周期。 1、全局作用域(G...

  • JavaScript作用域学习笔记

    @(JS技巧)[JavaScript, 作用域] JavaScript作用域学习笔记 概念: 作用域就是变量与函数...

  • 我的JS笔记 -- 作用域

    作用域和作用域链概念 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaSc...

网友评论

      本文标题:函数与作用域

      本文链接:https://www.haomeiwen.com/subject/svzuwxtx.html