深入Javascript函数、递归与闭包(执行环境、变量对

1、JavaScript中定义函数有2钟方法:

  1-1.函数声明:

复制代码 代码如下:


function funcName(arg1,arg2,arg3){
  //函数体
}


    ①name属性:可读取函数名。非标准,浏览器支持:FF、Chrome、safari、Opera。
    ②函数声明提升:指执行代码之前会先读取函数声明。即函数调用可置于函数声明之前。

  1-2.函数表达式:

复制代码 代码如下:


var funcName = function(arg1,arg2,arg3){
  //函数体
};


    ①匿名函数(anonymous function,或拉姆达函数):function关键字后无标识符,name属性值为空字符串。在把函数当成值使用时,都可用匿名函数。
    ②类似其他表达式,函数表达式使用前需先赋值,故不存在"函数声明提升"那样的作用。
    ③ECMAScript中的无效函数语法:

复制代码 代码如下:


if判断中的重复函数声明

if(condition){
    function sayHi(){
        alert("Hi!");
    }
} else {
    function sayHi(){
        alert("Yo!");
    }
}


      浏览器JavaScript引擎修正错误差异:大多浏览器会返回第二个声明,忽略condition;FF则会在condition为true时返回第一个声明。
      使用函数表达式可解决并实现:

复制代码 代码如下:


if判断 函数表达式

var sayHi;
if(condition){
    sayHi = function(){
        alert("Hi!");
    }
} else {
    sayHi = function(){
        alert("Yo!");
    }
}


2、递归
  递归函数,是在一个函数中通过名字调用自身的情况下构成的。

复制代码 代码如下:


function factorial(num){   //一个经典的递归阶乘函数
    if (num <= 1){
        return 1;
    } else {
        return num * factorial(num-1);
    }
}


     ①若使用下列代码调用该函数,会出错:

复制代码 代码如下:


var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4));


      将factorial()函数保存到变量anotherFactorial中后,将factorial变量设为null后不再引用函数,而anotherFactorial(4)中要执行factorial()函数,故出错。
      使用argument.callee(指向正在执行的函数的指针)可解决:

复制代码 代码如下:


解决方案

function factorial(num){
    if (num <= 1){
        return 1;
    } else {
        return num * arguments.callee(num-1);
    }
}

var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4));  //24


    在非严格模式,使用递归函数时,用argument.callee代替函数名更保险
    在严格模式下,使用argument.callee会出错,可用函数表达式 代替 函数声明:

复制代码 代码如下:


函数表达式代替函数声明

var factorial = function f(num){
    if (num <= 1){
        return 1;
    } else {
        return num * f(num-1);
    }
}


4、闭包

  指有权访问另一个函数作用域中的变量的函数。(常见形式为函数嵌套)

复制代码 代码如下:


function wai(pro){
    return function(obj1,obj2){
        var val1 = obj1[pro];
        var val2 = obj2[pro];
        if(val1<val2){
            return -1;
        }else if(val1>val2){
            return 1;
        }else{
            return 0;
        };
    }
}


    return匿名函数时,匿名函数的作用域链初始化为包含函数的活动对象和全局变量对象。即匿名函数包含wai()函数的作用域。
  每个函数被调用时,会创建一个执行环境、一个变量对象 及 相应的作用域链。

4-1.执行环境 及 作用域

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdgjdj.html