[JavaScript高级程序设计]函数表达式

函数表达式

定义函数有两种方式:一是函数声明,二是函数表达式。函数声明有一个重要特征是函数声明提升。

匿名函数:function关键字后面没有标识符。

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 闭包与变量

闭包只能取得包含函数中任何变量的最后一个值。

function createFunctions(){
    var results = [];
    for(var i=0;i<10;i++){
        results[i] = function(){
            return i;
        };
    }
    return results;
}
console.log(createFunctions().toString());    //10,10,10,...,10

2.2 this对象

匿名函数的执行环境具有全局性,因此其this对象通常指向window。

2.3 内存泄漏

(IE的某些版本中)如果闭包的作用域链中保存着一个HTML元素,那么意味着该元素将会无法被销毁。因为这些版本中对于JavaScript访问COM使用引用计数的垃圾收集机制。

/*
*匿名函数保存了一个对assignHandler()的活动对象的引用,因此就会导致无法减少element的引用计数,至少为1
*/
function assignHandler(){
    var element = document.getElementById('ele');
    element.onclick = function(){
        alert(element.id);
    }
}

/*
* 改进方法:
*/
function assignHandler(){
    var element = document.getElementById('ele');
    var id = element.id;
    element.onclick = function(){
        alert(id);
    }
    element = null;
}

3 模仿块级作用域

用作块级作用域的你ing函数与法如下:

(function(){
    //这里是块级作用域
})();

无论在什么地方,只要临时需要一些变量,就可以使用私有作用域

function outputNumbers(count){
    (function(){
        for(var i=0;i<count;i++){
            alert(i);
        }
    })();
    alert(i);    //error
}

4 私有变量

在JavaScript中没有私有成员的概念,所有对象属性都是公开的,但是有一个私有变量的概念:任何在函数中定义的变量都可以认为是私有变量,因为在函数外部无法访问这些变量。私有变量包括函数的参数,局部变量和在函数内部定义的其他函数。

扫描二维码关注公众号,回复: 2718374 查看本文章

我们把有权访问私有变量和私有方法的公有方法称为特权方法。有两种在对象上传建特权方法的方式:第一种是在构造函数内部创建特权方法。

function myObject(){
    var privateVariable = 10;
    funtion privateFunction(){
        return false;
    }
    this.publicMethod = function(){
        privateVariable++;
        return privateFunction();
    };
}

4.1 静态私有变量

通过在私有作用域中付那个意思有变量和函数,同样也可以创建特权方法。这个方法与在构造函数中定义特权方法的区别是:私有变量和函数是由实例共享的。

(function(){
    var name = "";
    Person = function(value){
        name = value;
    };
    Person.prototype.getName = function(){
        return name;
    };
    Person.prototype.setName = function(value){
        name = value;
    };
})();

var p1 = new Person('Nicholas');
console.log(p1.getName);    //'Nicholas'
p1.setName('Gred');
console.log(p1.getName);    //'Gred'

var p2 = new Person('Michael');
console.log(p1.getName);    //'Michael'
console.log(p2.getName);    //'Michael'

4.2 模块模式

模块模式是为单例创建私有变量和特权方法的。所谓单例,指的就是只有一个实例的对象。暗战管理,JavaScript是以对象字面量的方式来创建单例对象的。

var application = function(){
    var components = new Array();
    components.push(new BaseComponent());
    return{
        getComponentCount:function(){
            return components.length;
        },
        registerComponent:function(component){
            if(typeof component === 'oject'){
                components,push(component);
            }
        }
    };
}();

-----------------------------------------------拓展部分:--------------------------------------------------

单例模式:

1.模块模式:

function SingleWaiter(id,name,salary){
    Staff.call(this,id,name,salary);
}

SingleWaiter.getInstance = function(id,name,salary){
    var instance;
    return function(id,name,salary){
        if(!instance){
            instance = new SingleWaiter(id,name,salary);
        }
        return instance;
    }
}();

2.函数接口

function SingleWaiter(id,name,salary){
    Staff.call(this,id,name,salary);
    this.instance = null;
}

SingleWaiter.getInstance = function(id,name,salary){
    if(!this.instance){
        this.instance = new SingleWaiter(id,name,salary);
    }
    return this.instance;
}();

3.属性判断

function SingleWaiter(id,name,salary){
    Staff.call(this,id,name,salary);
    if(SingleWaiter.prototype.instance){
        return SingleWaiter.prototype.instance;
    }
    SingleWaiter.prototype.instance = this;
}

-------------------------------------------------拓展结束---------------------------------------------------

4.3 增强的模块模式

在返回对象之前加入对其增强的代码。这种增强的模块模式适合那种单例必须是某种类型的实例,同时还必须添加某些属性和(或)方法对其加以增强的情况。

var application = function(){
    var components = new Array();
    components.push(new BaseComponent());

    //要求application对象必须是BaseComponent类型的
    var app = new BaseComponent();
    app.getComponentCount = function(){
            return components.length;
    };
    app.registerComponent = function(component){
        if(typeof component === 'oject'){
            components,push(component);
        }
    }
    return app;
}();

猜你喜欢

转载自blog.csdn.net/Liwen_Ye/article/details/81461687