JavaScript函数表示式

一、创建
    1.函数声明      特征:函数声明提升,即函数调用要后于函数定义
    2.函数表达式
    eg:
        // 函数表达式
        function handle() {
            return 0;
        }
        use();      // 不可
        // 函数声明
        var use = function () {
            return 1;
        }
        use();      // 1
二、递归    即函数本书通过函数名调用自己
    eg:
        function handle(num) {
            if (num <= 1) {
                return 1;
            }  else {
                return num * arguments.callee(num - 1);
            }
        }
        alert(handle(5));       // 120 = 5 * 4 * 3 * 2 * 1
三、闭包    是指有权访问另一个函数作用域中的变量的函数
    eg:
        function handle() {
            var i = 10;
            return function () {
                return i * 10;      // 调用了另一个作用域handle函数中的i变量
            }
        }
        alert(handle()());          // 100
    1.闭包与变量 
        ①闭包只能取得函数中任意变量的最后一个值
        eg:
            function handle() {
                var res = [];
                for (var i = 0; i < 10; i++) {
                    res[i] = function () {
                        return i;
                    }
                }
                return res;
            }
            for(var i = 0, len = handle().length; i < len; i++) {
                alert(handle()[i]());       // return: 10个10
            }
        ②解决方法   创建一个匿名函数
        eg:
        function handle() {
            var res = [];
            for (var i = 0; i < 10; i++) {
                res[i] = function(num) {    // 创建一个匿名函数,让函数中的变量值执行完后就销毁
                    return function () {
                        return num;
                    }
                }(i);
            }
            return res;
        }
        for(var i = 0, len = handle().length; i < len; i++) {
            alert(handle()[i]());       // return: 10个10
        }       
    2.关于this对象。 
        ①问题 由于this的值是根据所在作用域而绑定的,因此在闭包中可能出现问题
        eg:
        var name = "zhang";
        var o = {
            name : "li",
            getName : function () {
                // alert(this); // [object Object]
                return function () {
                    // alert(this); // [object Window], 闭包中的this执行window
                    return this.name;
                }
            }
        }
        alert(o.getName()());           // zhang
        ②解决方法   将对象中的this对象保留下来,然后在闭包中调用
        eg:
        var name = "zhnag";
        var o = {
            name : "li",
            getName : function () {
                // alert(this); // [object Object]
                var that = this;        // [object Object]
                return function () {
                    return that.name;
                }
            }
        }
        alert(o.getName()());           // li
四、模仿块级元素
    ①问题 像iffor语句都不是块级元素,即其中定义的变量在外部可访问
        eg:
        for(var i = 0; i < 10; i++) {

        }
        alert(i);       // 10 
    ②解决方法   模仿块级元素,将其中的变量封装在for或者if语句中
        eg:
        (function () {  
            for(var i = 0; i < 10; i++) {}
        })();   // 匿名函数,执行完毕后立即被统统销毁,不留遗憾
        alert(i);       // 报错
五、私有变量
    1.引子    
        ①私有变量   即函数中的参数、定义的变量和函数
        ②特权方法   即在函数中可以访问私有私有变量和私有函数的公共方法
            eg:
            // 第一种方法
            function Person () {
                var name = "yang";          // 私有变量
                function getName() {        // 私有函数
                    return true;
                }
                this.publicMethod = function () {   // 公共方法
                    name = "li";
                    return getName();
                }
            }
            var p = new Person();
            alert(p.name);      // undefined
            alert(p.getName);       // undefined
            alert(p.publicMethod());        // true
            // 第二种方法
            function Person (name) {
                this.setName = function (value) {
                    name = value;
                }
                this.getName = function () {
                    return name;
                }
            }
            var p = new Person("yang");
            alert(p.name);      // undefined
            alert(p.getName());     // yang
            p.setName("chao");
            alert(p.getName());     // chao
    2.静态私有变量        在私有环境中,定义私有变量和私有函数,同样也可以定义公共方法
        eg: 
        (function () {
            var name = "";
            // 将构造函数写成函数表示且没有var,为全局变量
            Person = function (value) {
                name = value;
            }
            Person.prototype.setName = function (value) {
                name = value;
            }
            Person.prototype.getName = function() {
                return name;
            }
        })();
        var p1 = new Person("yang");
        alert(p1.getName());        // yang
        p1.setName("zhang");
        alert(p1.getName());        // zhang
        var p2 = new Person("li");
        alert(p1.getName());        // li
        alert(p2.getName());        // li
    3.模块模式  指在单例中定义私有变量和特权方法,单例是只有一个实例的对象。
        ①应用环境:  如果必须创建一个对象并以某些数据初始化,同时还有公开能够访问这些私有变量的公共方法
        ②案例:
            var single = (function () {
                // init data
                var name = "rihui";
                var raiseMoney = function () {
                    return 1000;
                }
                // alert(this); // [object Window]
                // 公共方法,外部接口
                return {
                    // _this : this // [object Window]
                    getName : name,
                    getMoney : function () {
                        return raiseMoney();
                    }
                };
            })();
            alert(single.getName);          // rihui
            alert(single.getMoney());       // 1000
    4.增强版的模块模式
        ①环境 可以规定返回的类型
        ②案例
            var Student = function () {
                this.buyGood = function () {};
                this.payMoney = function () {};
            };
            var single = (function () {
                // init data
                var goodName = "apple";
                var goodPrice = function () {
                    return 10;
                }
                // 公共方法,外部接口
                // 规定返回的类型:Student对象
                var object = new Student();
                object.buyGood = function () {
                    return goodName;
                };
                object.payMoney = function () {
                    return goodPrice();
                }
                return object;
            })();
            alert(single.buyGood());            // apple
            alert(single.payMoney());       // 10

你可能感兴趣的:(函数,递归,闭包,私有变量,模仿块级元素)