任务17

2016-11-04  本文已影响21人  璐璐熙可

问答

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

函数声明:


函数表达式:


函数声明:函数调用可以发生在函数声明之前,例如下面这种情况下不会报错


函数表达式:函数调用只能在函数表达式后面,不能在函数表达式前面,例如下面这种情况就会报错


综上所述函数声明和函数表达式的区别是:
函数声明会产生函数的声明前置,因此可以把函数的调用写在函数声明之前;但函数表达式只能产生变量的声明前置,如果把调用放在函数表达式之前则会报错。
函数声明语句之后不加分号;函数表达式是一个语句结尾需加分号。

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

var age;
console.log(age);//此时age被声明但没有被赋值,所以结果为undefined;
age=10;

3.arguments 是什么?

在函数内部,可以使用arguments对象获取到该函数的所有传入参数,类似数组.

function printPersonInfo(name, age, sex) {
    console.log(name);
    console.log(age);
    console.log(sex);
    console.log(arguments);
}
printPersonInfo('liu', 18, 'nan');
输出的结果为:

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

在JS中没有函数重载的概念,函数通过名字确定唯一性,参数不同也被认为是相同的函数,后面的覆盖前面的。所以只要在函数体内做好处理就行。

function sum(a,b){
    console.log(a+b);
}
function sum(a,b,c){
    console.log(a+b+c);
}
sum(1,4,5);

最后的结果为10.

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

立即执行函数表达式:指的是不需要进行函数的调用立即执行,可以将写在函数体内的语句立即执行。

function  name() {
    console.log('lulu');
}
name();
//这种写法必须通过name()调用后才可以执行,function name(){}只是声明这个函数,并没有执行。
//我们可通过对整个函数加小括号来使函数声明变成函数表达式,从而立即执行:
有两种写法:
(function name() {
   console.log('lulu');
})();
或
(function name() {
    console.log('lulu');
}());

作用:让这段代码拥有自己的作用域,主要是这是一个表达式,所以不会前置,而且立即执行后,在其他地方也无法调用.

6.什么是函数的作用域链?

函数的作用域链指的是:js中的作用域在函数里形成,我们在执行代码过程中,函数里可以使用函数中定义的变量,如果函数里没声明这个变量,它会直接访问到这个函数作用域外的全局变量.

for(var i=0; i<10; i++){
    var j=200;
}
//for循环无作用域,它没有局部作用域;
function k() {
    console.log(i);//程序在执行前,会提取程序中var声明的变量,但不提取赋值,这就是变量的声明前置,结果为undefined.
    var i=100;
    function k2() {
        i=99;//此时i没被声明,就从它的上一级去找被声明的变量i.
    }
    k2();
    console.log(i);//从它的上一级找到了var i=100;因为函数k2中的i赋值为99,所以把99赋给我们再上一级中找到的的var i=100,也就是此时var i=99;所以最后输出的结果为99;
}
k();
console.log(i);//没加var相当于声明全局变量.for循环中的i的结果为10,所以此时的结果为10;

代码

1.以下代码输出什么?

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('hunger', 28, '男');
//name:hunger
//age:28
//sex:男
//["hunger", 28, "男"]
//name:valley

getInfo('hunger', 28);
//name:hunger
//age:28
//sex:undefined
//["hunger", 28]
//name:valley

getInfo('男');
//name:男
//age:undefined
//sex:undefined
//["男"]
//name:valley

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

function sumOfSquares(){
    var sum=0;
    for(var i=0; i<arguments.length; i++){
        sum+=arguments[i]*arguments[i];
    }
    return sum;
}
sumOfSquares(2,3,4);   // 29
sumOfSquares(1,3);   // 10

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

console.log(a);//程序在执行前,会提取程序中var声明的变量,但不提取赋值,这就是变量的声明前置,结果为undefined.
var a = 1;
console.log(b);//报错b is not defined,变量b没有被声明所以报错;

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

sayName('world');
sayAge(10);
function sayName(name){
    console.log('hello', name);//hello world 由于存在函数声明前置的现象,所以在此调用之前函数sayName已经声明完毕,可以正常调用。
}
var sayAge = function(age){
    console.log(age);//报错:sayAge is not a function,因为sayAge是一个函数表达式,所以遵从的是变量的声明前置。但虽然声明前置,但赋值仍在此调用之后。所以sayAge被当成一个普通变量而非函数进行处理,因此这里作为函数进行调用时会报错。
};

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

function fn(){}
var fn = 3;
console.log(fn);
等价于
var fn;//因为变量声明的优先级高于函数声明所以先变量声明再函数声明
function fn(){}
fn=3;//fn赋值为3;
console.log(fn);//结果为3,当在同一个作用域内定义了名字相同的变量和方法的话,无论其顺序如何,变量的赋值会覆盖方法的赋值;

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

function fn(fn2){
       console.log(fn2);
       var fn2 = 3;
       console.log(fn2);
       console.log(fn);
       function fn2(){
       console.log('fnnn2');
        }
     }
fn(10);

上述代码可以转换为如下代码:
function fn(fn2) {//在函数fn()的局部作用域下,函数fn2()和变量fn2都提升到该作用域的顶部.
    var fn2;//声明变量
    function fn2() {//声明函数
        console.log('fnnn2');//由于函数fn2()与变量fn2重名,函数执行时载入的顺序是变量,函数,参数;函数覆盖变量,所以得到的是函数fn2()极其函数体内部的代码.
    }
    console.log(fn2);
    fn2=3;
    console.log(fn2);//fn2此时被赋值为3,输出结果为3
    console.log(fn);//在函数的作用域中找不到fn,所以会在全局中找,所以会输出整个fn函数.
}
fn(10);

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

var fn = 1;
    function fn(fn){
         console.log(fn);
    }
console.log(fn(fn)); 

上面的代码等价于

var fn;
    function fn(fn){        // 声明名为fn的函数,并且有一个fn的参数
        console.log(fn);    
    }
    fn = 1;                 // fn不再是函数,变成1
    console.log(fn(fn));    // 此时fn是1,即number类型。不再是函数,所以报错,fn is not a function

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

//作用域
    console.log(j);//undefined jS中只有函数才具有作用域,普通循环语句不会改变作用域,循环体内变量提升未被赋值;
    console.log(i);//undefined同上
    for(var i=0; i<10; i++){
        var j = 100;
    }//循环结束时候i=10;j=100;
    console.log(i);//10 执行循环后i值变为10
    console.log(j);//100 循环体里j的值是100

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

fn();
    var i = 10;
    var fn = 20;
    console.log(i);
    function fn(){
        console.log(i);
        var i = 99;
        fn2();
        console.log(i);
        function fn2(){
            i = 100;
        }
    }
上述代码的执行顺序实际上是:
var i;//变量i声明前置
var fn;//变量fn声明前置
function  fn() { //定义一个函数fn
  var i;//函数fn中先声明i
  function fn2() { //再定义函数fn2
      i=100;
 }
console.log(i);//因为此时fn2()函数没有被调用,所以i没有被赋值,i仅被声明但没有赋值,所以输出结果为undefined
    i=99;//i赋值为99
    fn2();//此处调用了fn2()函数,但是函数fn2中的i赋值为100
    console.log(i);//此时输出结果为100
}
fn();
i=10;//此处i被重新赋值为10
fn=20;
console.log(i);//此时输出结果为10

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

var say = 0;
(function say(n){//立即执行函数
    console.log(n);//初始传递的参数是10,第一次输出的结果为n=10,满足n<3这个条件,此时执行say(n-1);依此类推
    if(n<3) return;//当n=2时不满足条件,return跳出
    say(n-1);
}( 10 ));
console.log(say);//全局作用域中say=0,输出0;
依次输出:10,9,8,7,6,5,4,3,2,0
因为函数为立即执行函数,变量只在函数作用域内生效,并不会影响到函数作用域外的变量.所以最后console.log(say)输出0.
上一篇下一篇

猜你喜欢

热点阅读