JavaScript高级程序设计笔记(5)

第七章 函数表达式

  1. ,定义函数的方式有两种:一种是函数声明,另一种就是函数表达式。
    函数声明:
    sayHi();
    function sayHi(){
    alert(“Hi!”);
    }
    不会报错,因为在代码执行之前会先读取函数声明。
    函数表达式:
    var functionName = function(arg0, arg1, arg2){
    //函数体
    };

  2. 编写递归函数时
    var factorial = (function f(num){
    if (num <= 1){
    return 1;
    } else {
    return num * f(num-1);
    }
    });
    以上代码创建了一个名为f()的命名函数表达式,然后将它赋值给变量factorial。即便把函数
    赋值给了另一个变量,函数的名字f 仍然有效,所以递归调用照样能正确完成。这种方式在严格模式和
    非严格模式下都行得通。

  3. 闭包是指有权访问另一个函数作用域中的变量的函数。
    闭包有权访问包含函数内部的所有变量,原理如下。
     在后台执行环境中,闭包的作用域链包含着它自己的作用域、包含函数的作用域和全局作用域。
     通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。
     但是,当函数返回了一个闭包时,这个函数的作用域将会一直在内存中保存到闭包不存在为止。
    副作用,即闭包只能取得包含函数中任何变量的最后一个值。别忘了闭包所保存的是整个变量对象,而不是某个特殊的变量。
    function createFunctions(){
    var result = new Array();
    for (var i=0; i < 10; i++){
    result[i] = function(){
    return i;
    };
    }
    return result;
    }

    这个函数会返回一个函数数组。表面上看,似乎每个函数都应该返自己的索引值,即位置0 的函数返回0,位置1 的函数返回1,以此类推。但实际上,每个函数都返回10。因为每个函数的作用域链中都保存createFunctions() 函数的活动对象, 所以它们引用的都是同一个变量i 。当createFunctions()函数返后,变量i 的值是10,此时每个函数都引用着保存变量i 的同一个变量对象,所以在每个函数内部i 的值都是10
    我们可以通过创建另一个匿名函数强制让闭包的行为符合预期,如下所示。
    function createFunctions(){
    var result = new Array();
    for (var i=0; i < 10; i++){
    result[i] = function(num){
    return function(){
    return num;
    };
    }(i);
    }
    return result;
    }

  4. 闭包会引用包含函数的整个活动对象,而其中包含着element。即使闭包不直接引用element,包含函数的活动对象中也仍然会保存一个引用。因此,有必要把element 变量设置为null。这样就能够解除对DOM 对象的引用,顺利地减少其引用数,确保正常回收其占用的内存。

  5. function(){
    //这里是块级作用域
    }(); //出错!

    这段代码会导致语法错误,是因为JavaScript 将function 关键字当作一个函数声明的开始,而函
    数声明后面不能跟圆括号。然而,函数表达式的后面可以跟圆括号。要将函数声明转换成函数表达式,
    只要像下面这样给它加上一对圆括号即可。
    (function(){
    //这里是块级作用域
    })();

  6. 无论在什么地方,只要临时需要一些变量,就可以使用私有作用域,例如:
    function outputNumbers(count){
    (function () {
    for (var i=0; i < count; i++){
    alert(i);
    }
    })();
    alert(i); //导致一个错误!
    }

    这种做法可以减少闭包占用的内存问题,因为没有指向匿名函数的引用。只要函数执行完毕,就可以立即销毁其作用域链了。

  7. 在这个函数内部,有3 个私有变量:num1、num2 和sum。在函数内部可以访问这几个变量,但在
    函数外部则不能访问它们。如果在这个函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访
    问这些变量。而利用这一点,就可以创建用于访问私有变量的公有方法.
    我们把有权访问私有变量和私有函数的公有方法称为特权方法(privileged method)。有两种在对象
    上创建特权方法的方式。第一种是在构造函数中定义特权方法,基本模式如下。
    function Person(name){
    this.getName = function(){
    return name;
    };
    this.setName = function (value) {
    name = value;
    };
    }
    var person = new Person("Nicholas");
    alert(person.getName()); //"Nicholas"
    person.setName("Greg");
    alert(person.getName()); //"Greg"

  8. 通过在私有作用域中定义私有变量或函数,同样也可以创建特权方法
    (function(){
    //私有变量和私有函数
    var privateVariable = 10;
    function privateFunction(){
    return false;
    }
    //构造函数
    MyObject = function(){
    };
    //公有/特权方法
    MyObject.prototype.publicMethod = function(){
    privateVariable++;
    return privateFunction();
    };
    })();

  9. 模块模式(modulepattern)则是为单例创建私有变量和特权方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值