zoukankan      html  css  js  c++  java
  • 14 函数-高级

    1 匿名函数

    这种形式看起来好像是常规的变量赋值语句,即创建一个没有名称的函数(即匿名函数)并将它赋值给变量 add。

    这种情况下创建的函数叫做匿名函数(anonymous function),匿名函数有时候也叫拉姆达函数。

    2 递归

    写一个严格模式下的递归函数。

    "use strict"
    var factorial = (function f(num) {
        if(num <= 1){
            return 1;
        }else{
            return num * f(num - 1);
        }
    });
    console.log(factorial(5));

    3 闭包

    闭包是指有权访问另一个函数作用域中的变量的函数

    一个最简单的闭包例子:

    function f1(){
        var n = 999;
        nAdd = function(){
            n += 1;
        }
    }
    f1();
    nAdd();

    nAdd是定义在f1内部的,所以能够访问n,运行后,f1中的n会变成1000。

    其中的nAdd就是闭包。

    我们来验证一下:

    function f1(){
        var n = 999;
        nAdd = function(){
            n += 1;
        }
        function f2() {
            console.log(n);
        }
        return f2;
    }
    
    var result = f1();
    result(); // 999
    nAdd();   
    result(); //1000

    上面代码中,f2和nAdd都是闭包。

    上面代码中,将f2函数定义在f1内部,这样f2就能访问到f1中的变量了。

    运行f1,返回f2,即便f1已经运行完毕,这个f2依旧可以访问f1中的变量n,这个f2就是闭包

    可以参考:学习Javascript闭包

    再看一段代码:

    function compareFun(propertyName) {
        return function (obj1, obj2) {
            var value1 = obj1[propertyName];
            var value2 = obj2[propertyName];
         if(value1 > value2){
        return 1;
         }else if(value1 < value2){
        return -1;
         }else {
        return 0;
         }

    } };
    var compare = compareFun("age"); var result = compare({name: "a", age: 20}, {name: "b", age: 30}); console.log(result);

    在匿名函数从compareFun中被返回后,它的作用域链被初始化为包含compareFun函数的活动对象和全局变量对象。

    这样,匿名函数就可以访问在compareFun函数中定义的所有变量,更为重要的是,compareFun函数执行完后,其活动对象也不会销毁,

    因为匿名函数的作用域链中仍然在引用这个活动对象。

    上面代码的作用域链如下:

    4 闭包的缺陷

    5 闭包和变量

    别忘了闭包所保存的是整个变量对象(variable object),而不是某个特殊的变量。

    function compareFun() {
        var result = new Array();
        for(var i = 0; i < 3; i++){
            result[i] = function () {
                return i;
            }
        }
        return result;
    };
    var functionA = compareFun();
    console.log(functionA);
    console.log(functionA[0]);
    console.log(functionA[1]);
    console.log(functionA[0]());
    console.log(functionA[1]());

    运行结果都是3。

    因为每个函数的作用域链中都保存着 compareFun函数的活动对象,所以它们引用的都是同一个变量i,而最后i的值是3。

    如果要想每个函数返回的是变动的i,怎么做呢?

    function compareFun() {
        var result = new Array();
        for(var i = 0; i < 3; i++){
            result[i] = function (num) {
                return function () {
                   return num;
                };
            }(i);
        }
        return result;
    };

    看上去好像不太好理解,没事,来个简化版的:

    var x = function (num) {
        return function () {
            return num;
        };
    }(2);
    console.log(x);
    console.log(x());

    也就是说,执行x,返回的是匿名函数

    执行x(),将参数2赋值给num,并运行匿名函数。

    6 闭包中的this问题

    为什么执行闭包后,返回的是The Window,而不是My Object呢?

    前面曾经提到过,每个函数在被调用时都会自动取得两个特殊变量: this 和 arguments。

    内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量(这一点通过3中的图可以看得更清楚)。

    当闭包返回后,闭包是在全局环境中运行的,所以,this指的是window对象。

    如果是在严格模式下,运行结果是undefined。

    因为

     

    那要访问object中的name,怎么办?

    上面代码中的this,不再位于闭包中。

    当闭包返回后,调用的that是匿名函数中的变量that。

  • 相关阅读:
    img[src*="same"]{}
    a[href$=".pdf"]解释
    ::selection{}
    a[href^=""]的解释
    who are you?
    天下武功唯快不破
    登录一下好吗??
    后台登录
    实验吧—简单的登录题
    hdu 1010
  • 原文地址:https://www.cnblogs.com/lijy/p/6792235.html
Copyright © 2011-2022 走看看