JavaScript基础--函数声明,函数的作用域链

函数声明和函数表达式区别

函数声明是通过 function 函数名(){}来声明一个函数

函数表达式是通过声明一个变量,然后赋值函数。

两者区别是,在程序执行前,会先获取函数声明声明的函数,获取变量的声明,这里变量的声明只是先开辟一个空间,然后给了个名字,之后到该变量名赋值的时候,才有值,也就是说,在未得到该变量的赋值前,使用该变量会得到undefined。

而无论你把函数放在放在程序中的开头或者结尾,函数的执行语句都能正常执行。

fn();//输出   fn
console.log(fn2);// undefined 声明了,没有值,自动赋值undefined
function fn(){console.log('fn')}//函数声明
var fn2 = function(){console.log('fn2')};//函数表达式
fn2();//输出  fn2

变量的声明前置和函数的声明前置

变量的声明前置,在程序运行前,先获取变量的名字,到该变量的赋值语句,才为该变量赋值,再此前都是undefined。

函数的声明前置:function 函数名(){}声明了一个函数,在程序运行前,提取所有函数声明的函数,之后才正式开始运行函数,所以,无论函数声明的函数执行语句放在程序的最前面,或者程序的最后面,都能够正常执行。

例子:

fn();//输出1

function fn(){console.log(1)}

fn();//输出1

console.log(a);//undefined

var a = 2;

console.log(a);//输出2

arguments 是什么?

arguments是函数内部的一个对象,对应着传进来的参数,是一个类数组对象,没有数组的操作方法。

每个传进来的参数对应着arguments[0],arguments[1],有先后顺序之分。

比如function fn(name,age){

console.log(arguments[0];);

console.log(arguments[1];);

}

javascript中函数的重载?

在javascript中没有函数重载,因为相同的函数名字,如果定义的参数个数不一样,后出现的会覆盖先出现的。

所以,通过内部访问arguments可以不用管传进来多少个参数,尽管访问就可以了,但是传进来的参数有先后之分。

什么是立即执行函数表达式,作用是什么?

 1.(function(){})()

2.(function(){}())

作用:

1.函数会立即执行。

2.这个匿名函数中的变量与外部环境的变量隔离,防止了变量的命名冲突,形成了一个独立的空间,有助于代码模块化。

函数的作用域链是什么?

函数的作用域链:JavaScript没有块级作用域,只有使用函数来实现块级作用域,在全局环境下,是访问不到函数内部的变量,而函数可以访问外部的变量,而当函数内部有这个变量的时候,就不会去函数的作用域外去寻找。

当函数内部以及外部作用域都没有该变量的时候,会报undefined。总而言之,在函数内部有指定的要访问的变量的时候,不会往作用域外部去寻找,如果没有的话,就需要从函数的作用域外部去寻找,而外部的函数无法访问内部函数的变量,就是所谓的函数作用域链。

 

代码示例:

1.下面的代码输出什么

function getInfo(name, age, sex){

console.log('name:',name);//1

console.log('age:', age);//2

console.log('sex:', sex);//3

console.log(arguments);//4

arguments[0] = 'valley';//5

console.log('name', name);//6

}

getInfo('hunger', 28, '男');

//输出:1.name:hunger,    2.age: 28,     3 sex:男,    4['hunger',28,'男'],   5 下标0赋值为valley,6valley

getInfo('hunger', 28); getInfo('男');

//输出:1.name:hunger  ,2  age:28,  3.sex:undefined  4.['hunger',28],5赋值,6valley

 

* 2.写一个函数,返回参数的平方和?如 (难度**)

function sumOfSquares(){
var sum = 0;
if(arguments.length>0){
for(var i=0;i<arguments.length;i++){
sum += arguments[i]*arguments[i];
}
}
return sum;
}

3.如下代码的输出?为什么 (难度*)

   sayName('world');//打印 hello world
    sayAge(10);//报错,sayAge不是一个函数,未赋值
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };

4.如下代码的输出?为什么 (难度***)

    function fn(fn2){
       console.log(fn2);//输出函数fn2
       var fn2 = 3;//赋值3
       console.log(fn2);//输出3
       console.log(fn);//输出函数fn
       function fn2(){
            console.log('fnnn2');
        }
     }
    fn(10);//返回undefined

5.如下代码的输出?为什么 (难度***)

    var fn = 1;
    function fn(fn){
         console.log(fn);
    }
    console.log(fn(fn)); //输出fn不是一个函数,因为函数声明提前,之后又被赋值覆盖了,所以fn不是一个函数

6.如下代码的输出?为什么 (难度****)

    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;
        }
    }
1.先执行函数fn
2.内部有i,但是赋值语句在后面,所以输出undefined
3.执行fn2,因为里面的函数没有i,所以执行完后,就把原先的i=99又赋值为100,
4.输出100
5.执行完函数fn了,把全局变量i赋值为10,fn赋值为20,
6.输出10

10.如下代码的输出?为什么 (难度*****)

    var say = 0;//变量声明
    (function say(n){
        console.log(n);
        if(n<3) return;
        say(n-1);
    }( 10 ));//立即执行函数,有自己独立的空间,所以不会覆盖外部的say变量
    console.log(say);
1.(function say(){console.log(n)})(10)先打印n,之后判断,如果小于3就返回
2.在未返回前,都打印一次n,之后递归调用自己,n-1,直到小于3。
3.依次打印:
立即执行函数:10,9,8,7,6,5,4,3,2
console.log(say):0

posted @ 2016-07-19 17:27  chenyuru  阅读(251)  评论(0编辑  收藏  举报