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

来源:互联网 发布:企业一套表软件 编辑:程序博客网 时间:2024/06/01 08:19

函数表达式

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

//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
原创粉丝点击