函数与作用域

2017-06-15  本文已影响0人  饥人谷_啦啦啦

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

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

3.arguments是什么?

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

例如:

<script language="JavaScript"> 
function f(length) 
{ 
    alert("高为:"+length); 
} 

function f(length,width) 
{ 
    alert("高为:"+length+",宽为:"+width); 
} 
</srcipt>
/* 上面这个段代码行不通,第一个函数会被第二个覆盖,不能实现 f(10)想要的效果。*/

但是我们可以这么做

<script language="JavaScript"> 
function f(length) 
{ 
    var len= arguments.length; 
    if(1 == len) 
    { 
        var width = arguments[1]; 
        alert("高为:"+length+",宽为:"+width); 
    } 
    else 
    { 
        alert("高为:"+length); 
    } 
} 
</srcipt>

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

var something= functiong (){
  console.log ( "hello")
}();

所以,我们只需要让浏览器明白,我们前面function (){} 是一个函数表达式就可以了,类似的方法有许多,而已加上各种运算符,让浏览器知道,我们这是一个函数表达式,这就可以了。类似的有很多。

求n!,用递归来实现

function doRecursion(n){
    if(n<0){
      console.log('You input a wrong number');
    }
    else if(n===0||n===1){
        return 1;
    }
    else if(n>0){
      return n*multiply(n-1);
    }
}

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('男');

// 倒数第三行调用函数 ,输出 name: 饥人谷,age:2,sex:男;['饥人谷',2,'男‘],name:valley
// 倒数第二行调用函数,输出 name:小谷,age:3;sex:undefined;['小谷',3,];name:valley;
//最后一行调用函数,输出name:男,age:undefined;sex:undefined;['男'];
name:valley;

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

   function sumOfSquares(){
      var sum=0;
      for (var i=0;i<arguments.length;i++){
        sum=sum+arguments[i]*arguments[i];
      }
      return sum;
   }
   var result = sumOfSquares(2,3,4);
   var result2 = sumOfSquares(1,3);
   console.log(result) ;
   console.log(result2) ;

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

    console.log(a); //undefined,变量提升,有变量a,但是没有值。
    var a = 1;
    console.log(b);//error ,没有定义这个变量。

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

    sayName('world'); //hello,world.
    sayAge(10);//报错 。
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };

第一个函数能输出是因为,函数声明前置,可以找到globleContext的OA中有这个函数,然后就可以去执行这个函数的上下文。
第二个变量提升,浏览器不知道sayAge(10)是什么意思,如果放在函数表达式后面,浏览器就知道原来这个sayAge()是一个函数表达式,就会执行了。

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

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}

第一步:

globleContext{
  A0:{
  x:10,
  function foo(),
  bar(),
  }
  scope:null;
}
foo().[[scope]]=globleContext.AO
bar().[[scope]]=globleContext.AO

第二步:

执行bar();
在globloContext.AO中找到了 bar();
调用bar();进入bar()函数的barContext
barContext:{
  AO:{
    x:30,
  }
  scope:globleContext.AO
}
barContext.AO中没有找到 foo();然后去scope中找,scope指向globleContext.AO, 找到右foo();调用foo();
fooContext:{
  AO:{
    x:undefined,
  }
  scope:globleContext.AO
}
执行console.log(x);
但是在AO中没有找到,去scope中找到指向globleContext.AO,找到x的值为10,所以,最终结果就是10。

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}   
globleContext: {
  AO:{
    x:10,
    function bar(),
  }
  scope:null
}

bar.[[scope]]=globleContext.AO;

//第二部;
执行bar(); 在globleContext中找到。
进入bar();

barContext:{
  AO:{
    x=30;
    function foo();
  }
  scope:globleContext.AO
}

foo.[[scope]]=barContext.AO;

执行 foo(); 
foo()中没有找到x.去barContext.AO找到了。所以console.log(x);
结果是10。

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}
1、执行bar(),globleContext中有bar()
2 、进入bar()的上下文;
3、执行立即执行函数表达式,但是函数表达式AO中没有找到X,
4、去scope中找,找到的是barContext.AO中,有x的值,得到30.

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

var a = 1;

function fn(){
  console.log(a)
  var a = 5
  console.log(a)
  a++
  var a
  fn3()
  fn2()
  console.log(a)

  function fn2(){
    console.log(a)
    a = 20
  }
}

function fn3(){
  console.log(a)
  a = 200
}

fn()
console.log(a)
1、执行fn() 在globleContext中找到了,所以,进入fn()的上下文。
2、console.log(a),当前函数的作用域中有a变量,此时没有赋值//输出 **undefined**
3、再次执行console.log(a),上一行,a已经赋值,所以//输出 **5**
4、a++ ; a=6,不用输出。
5、var a, a仍然等于6.
6、执行fn3() ,当前函数的AO中没有,找到globleContext.AO,有fn3(),进入fn3()的上下文中。
7、console.log(a),当前的AO还没有a,所以,去找到上一级的AO,找到globleContext.AO,然后,得到结果// **1**,顺便,修改了globleContext.AO中的a=200;
8、回到fn(),运行fn2(),找到了fn2(),进入fn2(), console.log(a), 当前AO中没有a,找到上一级也就是fn的AO中,a=6 ,所以输出 ** 6 ** ,顺便修改了fnContext中的AO,是20 。
9、执行fn()中的console.log(a),此时受到第8步骤的影响,所以,输出是**20.**
10 、fn()运行结束,此时,再次运行console.log,受到第7 的影响,a变为了200.所以输出**200**
上一篇 下一篇

猜你喜欢

热点阅读