JS高级程序设计读书笔记(第七章)

函数表达式

定义函数有两种方式:一种是函数声明,另一种就是函数表达式

//1,函数声明
function functionName(arg0, arg1, arg2){
    //函数体
}
    //函数声明的一个重要特征是,函数声明提升,意思是在执行代码之前会先读取函数声明。而函数表达式没有这个特征。
    eg: sayHi();
        function sayHi(){
            alert('Hi!');
        }
//2,函数表达式
var functionName = function(arg0, arg1, arg2){
    //函数体
}

 

1. 递归

 
在非严格模式下使用arguments.callee,它是一个指向正在执行的函数的指针,可以用它来代替函数名实现对函数的递归调用。在严格模下可以使用命名函数表达式来达到相同的结果。

function factorial(num){
    if(num <=1){
        return 1;
    }else{
        return num * factorial(num-1);
    }
}
//非严格模式
function factorial(num){
    if(num <=1){
        return 1;
    }else{
        return num * arguments.callee(num-1);
    }
}
//严格模式
var factorial = {
    function f(num){
    if(num <=1){
        return 1;
    }else{
        return num * f(num-1);
    }
}

 

2. 闭包

 

闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式是在一个函数内部创建另一个函数。
 

2.1 关于this对象

 
在全局函数中,this等于window。

var name = 'the window';
        var obj = {
            name : 'the obj',
            getNameFunc : function(){
                return this.name;
            }
        }

alert(obj.getNameFunc());                       //'the obj'
alert((obj.getNameFunc)());                     //'the obj'        
alert((obj.getNameFunc = obj.getNameFunc)());   //'the window'


var name = 'the window';
        var obj = {
            name : 'the obj',
            getNameFunc : function(){
                return function(){
                    return this.name;
                }
            }
        }

alert(obj.getNameFunc()());       //'the window'

//把this对象保存在闭包中的另一个可以访问到的变量中。

var name = 'the window';
        var obj = {
            name : 'the obj',
            getNameFunc : function(){
                var that = this;
                return function(){
                    return that.name;
                }
            }
        }

alert(obj.getNameFunc()());       //'the obj'

 

3. 模仿块级作用域

 
JS没有块级作用域,但是可以将语句块包含在函数中模仿块级作用域。

var someFunc = function(){
    //函数体,这里是块级作用域
};  
someFunc();   //函数后面加括号,表示立即调用执行。但是只是针对函数表达式。

function(){
    //函数体,这里是块级作用域
}();         //出错,函数声明后面不能跟圆括号,但是可以给函数声明加上一对圆括号,表示将函数声明转换成函数表达式,如下所示。
(function(){
    //函数体,这里是块级作用域
})(); 

 

4. 私有变量

 
任何在函数中定义的变量,都可以认为是私有变量。我们把有权访问私有变量和私有函数的公有方法称为特权方法。有两种方法创建特权方法。

//方法一:在构造函数中定义特权方法
        function myObject(){
            //私有变量和私有函数
            var privateVariable = 10;

            function privateFunction(){
                return false;
            }
            //特权方法
            this.publicMethod = function (){
                privateVariable++;
                return privateFunction();
            }
        }
        //和第二种方法对比,构造函数中定义特权方法针对每个实例都会创建一组新的方法
        function Person(name){

            this.getName = function(){
                return name;
            };

            this.setName = function(value){
                name = value;
            };
        }

        var person1 =new Person('dan');
        var person2 =new Person('jun');
        alert(person1.getName());         //'dan'
        alert(person2.getName());         //'jun'
//方法二:在私有作用域中定义私有变量或函数,同样也可以创建特权方法
        (function(){
            //私有变量和私有函数
            var name = ''; //私有变量name在这种模式下变成了一个静态的,由所有实例共享的属性
            //初始化未经声明的变量,会创建一个全局变量
            Person = function(value){
                name = value;
            };
            //公有/特权方法
            Person.prototype.getName = function(){
                return name;
            };

            Person.prototype.setName = function(value){
                name = value;
            };
        })();

        var person1 = new Person('dan');
        alert(person1.getName());              //'dan'
        person1.setName('jun');
        alert(person1.getName());              //'jun'

        var person2 = new Person('jenny');
        alert(person1.getName());              //'jenny'
        alert(person2.getName());              //'jenny'

 

4.1 模块模式

 
前面的模式都是用于为自定义类型创建私有变量和特权方法,而模块模式则是为单例创建私有变量和特权方法。所谓单例,指的就是只有一个实例的对象,按照惯例,JS以对象字面量的方式来创建单例对象。

        var singleton = function(){
            //私有变量和私有函数
            var privateVariable = 10;

            function privateFunction(){
                return false;
            }

            //特权/共有方法和属性
            return {

                publicProperty: true,

                publicMethod: function(){
                    privateVariable++;
                    return privateFunction();
                }
            }
        }

简言之,如果必须创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法,那么就可以使用模块模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值