进阶3 函数与作用域无标题文章

1. 函数声明和函数表达式的区别
  • 函数声明:不必放在调用的前面
//函数调用
sum();
//函数声明
function sum(){
    var a=1;
    var b=1;
    c=a+b;
    return c;
}
  • 函数表达式:必须放在调用的前面
var sum=function(){
    var a=1;
    var b=1;
    c=a+b;
    return c;
}
sum();
2. 变量的声明前置和函数的声明前置
  • 变量的声明前置:当一个变量被定义时,在代码执行前会先将变量进行初始化再执行语句。
console.log(a);         声明前置后  var a;
var a =1;                         console.log(a);   // undefined
console.log(a);                    a =1 ;                                   
                                   console.log(a);  // 1     

  • 函数的声明前置:当函数以函数声明的方式声明时,代码执行前会首先生成该函数,然后再执行语句
sayHello();                     声明前置后  function sayHello(){
function sayHello(){                           console.log('hello');
    console.log('hello');                  }
}                                          sayHello();  //'hello'
3. arguments

arguments是一个类数组对象,可以传入function内部所有的参数(本地变量),但不是函数的属性,只在函数内部有效,写法是arguments[i]依次对参数进行访问和修改。

function printPersonInfo(name, age, sex){
    console.log(name);
    console.log(age);
    console.log(sex);
    console.log(arguments);
 }
4. 实现函数的"重载"

在js中没有函数的重载,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后出现的会覆盖先出现的,但可以在函数体针对不同的参数调用执行相应的逻辑,或通过arguments实现重载。

  • 通过传入参数实现重载
function userInfo(name,age,sex){ 
    if(name){ 
        console.log(name); 
    } 
    if(age){ 
        console.log(age); 
    } 
    if(sex){
         console.log(sex);
     } 
} 
userInfo("andy",22); //参数依次传递值,缺少的参数返回的是
undefined userInfo("andrea",20,"female");
  • 通过arguments来实现重载
function sum(){
    var  sum =0;
    for (var i =0; i<arguments.length; i++){
        sum += arguments[i];
    }
    return sum;
}
console.log(sum(1,2,3,4)); //输出结果为10
5. 立即执行函数表达式概念和作用
(function(){
  var a  = 1;
  console.log(a); //1
})()
console.log(a); //报错:Uncaught ReferenceError: a is not defined

其他写法

(function fn1() {
    var a  = 1;
    console.log(a); //1
})();
console.log(a); //报错:Uncaught ReferenceError: a is not defined
// 逗号也只能操作表达式
1, function fn3(){
      var a  = 1;
      console.log(a); //1
}();
console.log(a); //报错:Uncaught ReferenceError: a is not defined
!function(){
  var a  = 1;
  console.log(a); //1
}();
console.log(a); //报错:Uncaught ReferenceError: a is not defined
立即执行函数.jpg

作用:隔离作用域,防止了变量的命名冲突,形成独立的空间;可以让函数在定义后直接调用,在固有的作用域内使用,不会污染全局变量

6. 递归实现n!
function factor(n){
    if(n===1||n===0){
        return 1;
    }
    return n*factor(n-1);
}
7. 代码练习
以上代码输出什么?
getInfo('饥人谷',2,'男')输出结果:
name:饥人谷
age:2
sex:男
["饥人谷",2,"男"]
name valley
getInfo('小谷', 3)输出结果:
name:小谷
age:3
sex:undefined
["小谷",3]
name valley
getInfo('男')输出结果:
name:男
age:undefined
sex:undefined
["男"]
name valley
8. 写一个函数,返回参数的平方和
 function sumOfSquares(){
     var result=0;
     for(var i=0; i<arguments.length; i++){
         result+=arguments[i]*arguments[i];
     }
     return result;
 }
 var result = sumOfSquares(2,3,4)
 var result2 = sumOfSquares(1,3)
 console.log(result)  //29
 console.log(result2)  //10
9. 代码练习
以上代码输出什么?
变量声明前置:
var a;
console.log(a); //underfined,变量声明前置,初始值undefined 
a = 1; 
console.log(b); //报错:Uncaught ReferenceError:b is not defined,因为b没有声明
10. 代码练习
以上代码输出什么?
sayName('world')输出结果:
hello world
//函数声明不必放在调用的前面
sayAge(10)输出结果:
报错:Uncaught TypeError: sayAge is not a function
//函数表达式必须放在调用的前面
11. 代码练习

写出以下代码的输出结果和作用域链查找过程伪代码

11.png

输出结果:10
作用域链查找过程伪代码:
1.globalContext={
      AO:{
          x:10
          foo:function
          bar:function
      },
      Scope:null
  }
  foo.[[scope]]=globalContext.AO
  bar.[[scope]]=globalContext.AO

2.barContext={
      AO:{
          x:30
      },
      Scope:bar.[[scope]]
  }
  
3.fooContext={
      AO:{},
      Scope:foo.[[scope]]
  }
12. 代码练习

写出以下代码的输出结果和作用域链查找过程伪代码

12.png

输出结果:30
作用域链查找过程伪代码:
1. globalContext={
       AO:{
           x:10
           bar:function
       },
       Scope:null
   }
   bar.[[scope]]=globalContext.AO
2. barContext={
       AO:{
           x:30
           foo:function
       },
       Scope:bar.[[scope]]
   }
   foo.[[scope]]=barContext.AO
3. fooContext={
       AO:{},
       Scope:foo.[[scope]]
   }
13. 代码练习

写出以下代码的输出结果和作用域链查找过程伪代码

13.png

输出结果:30
作用域链查找过程伪代码:
1. globalContext={
       AO:{
           x:10
           bar:function
       },
       Scope:null
   }
   bar.[[scope]]=globalContext.OA
2. barContext={
       AO:{
           x:30
           function:function
       },
       Scope:bar.[[scope]]
   }
   function.[[scope]]=barContext.OA
3. functionContext={
       AO:{},
       Scope:function.[[scope]]
   }
14. 代码练习

写出以下代码的输出结果和作用域链查找过程伪代码

14.png
输出结果:undefined 5 1 6 20 200
作用域链查找过程伪代码:
1. globalContext = { 
        AO:{ 
            a:1 //200
            fn:function 
            fn3:function 
    }, 
   Scope:null 
   } 
   fn.[[scope]] = globalContext.AO 
   fn3.[[scope]] = globalContext.AO

 2.调用fn() 
    fnContext = { 
        AO:{ 
            a:undefined //5,6,20
            fn2:function
        }, 
        Scope:fn.[[scope]] //globalContext.AO 
    }
    fn2.[[scope]] = fnContext.AO 

3. fn3Context = { 
       AO:{ 
           a:200 
       }, 
       Scope:fn3Context.[[scope]] //globalContext.AO 
   } 

4. fn2ConText = { 
       AO:{ 
          a:20
       }, 
      Scope:fn2ConText.[[scope]] //fnContext.AO 
   }

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

推荐阅读更多精彩内容

  • 1.函数声明和函数表达式有什么区别 函数就是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同...
    徐国军_plus阅读 472评论 0 0
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,204评论 0 4
  • 函数声明和函数表达式有什么区别 函数声明语法:function functionName(arg0,arg1,ar...
    _Dot912阅读 564评论 0 3
  • 1.函数声明和函数表达式有什么区别 函数声明 代码执行时函数声明会被提升到最前执行,所以函数的调用与函数声明的顺序...
    Feiyu_有猫病阅读 367评论 0 0
  • (老文) 这三个字 我一个也不敢敲响 但你要相信 我始终守候着它们 虔诚匍匐 不曾远离 我只是怕 只是怕说出来的那...
    倾蓝半步阅读 428评论 9 15