js 高程学习总结 第七章 函数表达式

来源:互联网 发布:怎么知快怀孕了 编辑:程序博客网 时间:2024/06/16 13:04

定义函数有两种方式:函数声明,函数表达式
函数声明

function functionName(){    //函数体}

函数声明的一个重要特征:函数声明提升,在执行代码前会先读取函数声明。这意味着 将函数声明放在调用他的语句后面;
函数表达式:var functionName = function(){}
递归
递归函数是一个函数通过名字调用自身的情况下构成的
非严格模式下,可以写作:

var 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);    }})

闭包
闭包指的是有权访问另一个函数作用域中的变量的函数;
闭包会携带包含它的函数作用域,因此会占用更多内存,因此要慎重使用闭包
闭包和变量
闭包只能取得包含函数中任何变量的最后一个值。闭包所保存的是整个变量对象,而不是某个特殊的变量

function createFun(){    var result = new Array();    for(var i = 0;i < 10;i++){        result[i] = function(){            return i;        }    }    return result;}

会发现所有的i都会10;
解决方案:

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

关于this对象
this 对象运行时基于函数的执行环境绑定:在全局函数中this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象;不过匿名函数的执行环境有全局性,因此其this通常指向window;

var name = "window";var object = {    name: "My Object",    getNameFunc: function(){        var that = this;        return function(){            return that.name;        }    }}console.log(object.getNameFunc());//"My Object"
var name = "window";var object = {    name: "My Object",    getNameFunc: function(){                return this.name;    }}object.getName();//"My Object"(object.getName)();//"My Object"(object.getName = object.getName)();//"window"

内存泄漏
防止内存泄漏

function assignHandler(){    var element = document.getElementById("someElement");    var id = element.id;    element.onclick = function(){        console.log(id);//若直接应用element,会造成无法释放element    }    element = null;}

模仿块级作用域

js没有块级作用域的概念。这意味着块语句中定义的变量,实际上是在包含函数中而非语句中创建的;js从不会告诉你是否多次声明了同一个变量,遇到这种情况,它只会对后续的声明视而不见(不过,会执行后续声明中的变量初始化);
匿名函数可以用来模仿块级作用域避免这个问题

(function(){ })();function(){ }();//会报错,function是函数声明的开始,函数声明后面不能跟圆括号,而函数表达式后面可以跟圆括号

这是一个立即调用的匿名函数,将函数声明包含在一对圆括号中,表示实际上是一个函数表达式,这种做法可以减少闭包占用的内存问题,因为没有指向匿名函数的引用,只要函数执行完毕,就可以销毁其作用域链了。

我们应该尽量向全局作用域中少添加变量和函数

私有变量

定义在函数中的变量,都可以认为是私有变量,私有变量包括函数的参数,局部变量、函数内部定义的其他函数
把有权访问私有变量和私有函数的公有方法称为特权方法,
在构造函数中定义特权方法的缺点:构造函数会使每个实例都创建同一组新方法,使用静态私有变量可以避免这个问题
静态私有变量

(function (){    var privateVariable = 10;    function provateFunction(){        return false;    }    //构造函数,声明构造函数时没有使用函数声明(会创建成局部变量,也没有使用var ,因为初始化未经声明的变量,会创造一个全局变量;但是在严格模式下会导致错误)    MyObject = function(){};    MyObject.prototype.publicMethod = function(){        privateVariable ++;        return provateFunction();    }})();

但是同样会造成每个实例都没有自己的私有变量,即在prototype上操作的属性会变成一个静态的、由所有实例共享的属性;

模块模式
为单例创建私有变量和特权方法,

增强的模块模式

var application = function(){    //私有变量和函数    var compents = new Array();    //初始化    compents.push(new BaseComponent);    //创建application 的一个局部副本    var app = new BaseComponent();    //公共接口    app.getComponentCount = fucntion(){        return compents.length;    }    app.registerComponent = function(compent){        if(typeof compent === "object"){            compents.push(compent);        }    }    return app;}
0 0
原创粉丝点击