函数与作用域

1.函数声明和函数表达式有什么区别

  • 函数声明:function functionName(){};使用function关键字声明一个函数,再指定一个函数名,叫函数声明
    函数表达式:var fn = function(){};使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量fn,叫函数表达式,这是最常见的函数表达式语法形式
    -** 区别
    1.Javascript引擎在解析javascript代码时会‘
    函数声明提升’(Function declaration Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式**。
    2.函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。
   alert(foo); // function foo() {} 原因:变量声明提升
   alert(bar); // undefined:原因bar能提升,但是没赋值,默认为undefined
   function foo() {}   
    var bar = function bar_fn() {};
  alert(foo); // function foo() {}
  alert(bar); // function bar_fn() {}

2.什么是变量的声明前置?什么是函数的声明前置

  • 变量的声明前置:就是在一个作用域块中,所有的变量都被放在代码块的开始出处声明
  • 函数的声明前置:和变量的声明会前置一样,函数声明同样会前置。
  • 函数声明的前置为:声明和赋值均前置。
  • 函数表达式的前置为:仅仅声明前置,值为undefined,直到读到表达式后才取得表达式的值。

3.arguments 是什么

arguments是类数组对象,包含着传入函数中的所有参数。arguments 变量不是一个数组(Array)。 尽管在语法上它有数组相关的属性 length,但它不从 Array.prototype 继承,实际上它是一个对象(Object)。
因此,无法对 arguments 变量使用标准的数组方法,比如 push, pop 或者 slice。

eg:   function printPersonInfo(name, age, sex){ 
            console.log(arguments);
      }
    printPersonInfo("tiger",6,"boy")

4.函数的"重载"怎样实现

  • "重载"的概念:,是Ada、C++、C#、D和Java等编程语言中具有的一项特性,这项特性允许创建数项名称相同但功能的输入输出类型不同的子程序,它可以简单地称为一个单独功能可以执行多项任务的能力。
 其他语言的重载;
  int sum(int num1, int num2){
      return num1 + num2;
     }
  float sum(float num1, float num2){
    return num1 + num2;
  }
  sum(1, 2);
  sum(1.5, 2.4);
  • 在 JS 中没有重载! 同名函数会覆盖。 但可以在函数体针对不同的参数调用执行相应的逻辑
    function printPeopleInfo(name, age, sex){
    if(name){
    console.log(name);
    }
    if(age){
    console.log(age);
    }
    if(sex){
    console.log(sex);
    }
    }
    printPeopleInfo('Byron', 26); // 'Byron' 26
    printPeopleInfo('Byron', 26, 'male');// 'Byron' 26 'male'

5.立即执行函数表达式是什么?有什么作用

  • 英文:immediately-invoked function expression,缩写:IIFE,是一种利用JavaScript函数生成新作用域的编程方法。有时,这种编程方法也被叫做“自执行(匿名)函数”,但“立即调用函数表达式”是语义上最准确的术语。
  • 作用
    隔离作用域,保护私有变量,防止污染全局变量
  • 用法
    最常见的一种是将函数表达式字面量置于圆括号之内,然后使用圆括号调用函数。
    (置于圆括号内是因为:无论在全局环境或者局部环境里遇到了这样的function关键字,默认的,它会将它当作是一个函数声明,而不是函数表达式,如果你不明确的告诉圆括号它是一个表达式,它会将其当作没有名字的函数声明并且抛出一个错误,因为函数声明需要一个名字)
    (function() { // 这里的语句将获得新的作用域 })(); 若要将作用域外变量传递进函数,则按下述方式书写: (function(a, b) { // a == 'hello' // b == 'world' })('hello', 'world'); 在一些省略分号的程序中,可见将分号至于行首的做法。这样的分号被称为“防御性分号” a = b + c ;(function() { // 故意将分号放在这里 // 代码 })(); 如此书写,以防止语句被理解为对函数c的调用(c(...))。

6.求n!,用递归来实现

 function factorial(n){
    if(n<0){
      return "无效输入";
    }
    else if(n<=1){
        return 1;
    }else{
        return n*factorial(n-1) ;
    }
 }
  alert(factorial(5))//120

7.以下代码输出什么?

function getInfo(name, age, sex){
    console.log('name:',name);
    console.log('age:', age);
    console.log('sex:', sex);
    console.log(arguments);
    arguments[0] = 'valley';
    console.log('name', name);
}
  getInfo('饥人谷', 2, '男');
> getInfo('小谷', 3);
> getInfo('男');

8. 写一个函数,返回参数的平方和?

   function sumOfSquares(){
     var sum = 0;
            for(var i =arguments.length;i>0;i--){
                sum+=Math.pow(arguments[i-1],2);
            }
      return sum
   }
   var result = sumOfSquares(2,3,4)
   var result2 = sumOfSquares(1,3)
   console.log(result)  //29
   console.log(result2)  //10

9. 如下代码的输出?为什么

console.log(a); //undefined ;变量a声明提前,但未赋值 
var a = 1;
console.log(b);//b is not defined ;变量b没有声明和赋值

10. 如下代码的输出?为什么

sayName('world');// hello  world;函数声明的前置为声明和赋值均前置
sayAge(10);//sayAge is not a function ;函数声明前置,但表达式值不能前置,sayAge为undefined,undefined 没有方法。
function sayName(name){
    console.log('hello ', name);
}
var sayAge = function(age){
    console.log(age);
};

11. 如下代码输出什么? 写出作用域链查找过程伪代码

  var x = 10
  bar() //返回:10
  function foo() {
    console.log(x)
  }  
  function bar(){
    var x = 30
    foo()
}
globalContext={
  Ao:{
    x:10
    foo:function
    bar:function
  } ,
Scope:null
}
  //声明 foo 时 得到下面
  foo.[[scope]] = globalContext.Ao
  //声明 bar 时 得到下面
  bar.[[scope]] = globalContext.Ao
  //当调用 bar() 时, 进入 bar 的执行上下文
  barContext ={
      Ao:{
         x:30
      },
      Scope:bar.[[scope]]// globalContext.Ao
  }
当调用 foo() 时,先从 bar 执行上下文中的 AO里找,找不到再从 bar 的 [[scope]]里找找到后即调用
  //当调用 foo() 时,进入 foo 的执行上下文
  fooContext = {
      AO: {},
      Scope: foo.[[scope]] // globalContext.AO
  }
        所以 console.log(x)是 10

12. 如下代码输出什么? 写出作用域链查找过程伪代码

var x = 10;
bar() //返回30
function bar(){
    var x = 30;
    function foo(){
      console.log(x) 
}
  foo();
}   
 作用域查找过程伪代码
globalContext={
  Ao:{
    x:10
    bar:function
  } ,
Scope:null
}

  //声明 bar 时 得到下面
  bar.[[scope]] = globalContext.Ao
  //当调用 bar() 时, 进入 bar 的执行上下文
  barContext ={
      Ao:{
         x:30,
        foo:function
      },
      Scope:bar.[[scope]]// globalContext.Ao
  }
当调用 foo() 时,先从 bar 执行上下文中的 AO里找,找到后即调用
  //当调用 foo() 时,进入 foo 的执行上下文
  fooContext = {
      AO: {},
      Scope: foo.[[scope]] // barContext.AO
  }
        所以 console.log(x)是 30

13. 以下代码输出什么? 写出作用域链的查找过程伪代码

var x = 10;
bar() // 30
function bar(){
  var x = 30;
    (function (){
    console.log(x)
  })()
}
作用域链的查找过程伪代码
 globalContext = {
      Ao:{
        x:30
        bar:function
    },
      Scope:null
  }
 // 声明bar时,得到下面
  bar.[[scope]]=globalContext.Ao;
  //当调用bar时,进入bar的执行上下文;先从 bar 执行上下文中的 AO里找,找到后即调用
   barContext = {
      Ao:{
        x:30
        IIFE:function
      }
      Scope: bar.[[scope]]//globalContext.Ao
    }
  所以 console.log(x)是 30

14. 以下代码输出什么? 写出作用域链查找过程伪代码

var a = 1;
function fn(){
  console.log(a)//undefined
  var a = 5
  console.log(a)//5
   a++
   var a
   fn3()  
   fn2() 
   console.log(a) //20
   function fn2(){
    console.log(a)  //6
    a = 20   
  }
}
function fn3(){
  console.log(a)   //1
  a = 200
}
fn() //20
console.log(a)  //200
 //作用域链查找过程伪代码
globalContext = {
    Ao:{
        a:200
        fn:function 
        fn3:function
    },
    Scope:null
  }
 // 声明fn时,得到下面
fn.[[scope]] = globalContext .Ao
// 声明fn3时,得到下面
fn3.[[scope]] = globalContext .Ao


 fnContext={
    Ao:{
      a:20
      fn2:function
    }
    Scope:fn.[[scope]]// globalContext .Ao
  }

 fn3Context={
    Ao:{}
    Scope:fn.[[scope]]// globalContext .Ao
}

   // 声明fn2时,得到下面
    fn2.[[scope]] = fnContext .Ao
  
    fn2Context={
          Ao:{}
          Scope:fn.[[scope]]// fnContext .Ao
    }
所以 fn()是20  console.log(a)是200
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容

  • 1. 函数声明和函数表达式有什么区别 使用function关键字声明一个函数时,声明不必放到调用的前面。//函数声...
    _李祺阅读 261评论 0 0
  • 函数声明和函数表达式有什么区别? 函数声明和函数表达式是EMACScript规定的两种不同的声明函数的方法。1.函...
    LeeoZz阅读 341评论 0 1
  • 1,函数声明和函数表达式有什么区别 1、背景介绍 定义函数的方法主要有三种: 1:函数声明(Function De...
    进击的前端_风笑影阅读 426评论 0 0
  • 声明前置和作用域也是JS 部分面试常考点 1.函数声明和函数表达式有什么区别 函数声明:使用function关键字...
    湖衣阅读 194评论 0 0
  • 目标:1、希望孩子拥有更多朋友更加开心快乐!智慧多多!不计较!不抱怨! 2、希望我的学习可以让我通过税一税二考试。...
    zl向日葵阅读 113评论 0 0