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

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

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值