2

模仿块级作用域

在块级语句中定义的变量,实际上是包含函数中而非语句中创建的。如:

function outputNumbers(x){
    for (var i = 0; i < x; i ++){
        console.log(i);
    }
    var i; //即使重新声明了变量仍然不起作用
    console.log(i); //123
}
outputNumbers(4); //4

()()方法模仿块级作用域

通常用块级作用域(私有作用域)的匿名函数的语法来解决这个问题:

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

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

function outputNumbers(x){
    (function(){
        for (var i = 0; i < x; i ++){
            console.log(i);
        }
    })()
}
outputNumbers(4); //0123

又如:

function outputNumbers(x){
    (function(){
        for (var i = 0; i < x; i ++){
            console.log(i);
        }
    })()
    var i;
    console.log(i);  //undefined
}
outputNumbers(4);

这样一来,变量i 只能在循环中使用,使用后即被销毁。实际上他也属于闭包。

避免对全局作用域产生不良影响

这种方式可以通过创建私有作用域,避免对全局作用域产生不良影响。

var num = 100;
(function(){
    if (num > 10){
        console.log("greater than 10");
    }
})();

(function(){
    if (num > 10){
        console.log("greater than 10");
    }
})();
//两者完全一样,相互独立,互不影响

私有变量

在js 中,任何在函数中定义的变量,都可以认为是私有变量。一般包括函数的参数、局部变量和内部定义的其他函数。如:

function add(num1,num2){
    var sum = num1 + num2;
    return sum;
}

其中这个函数的内部就有3个私有变量:num1、num2 和sum。

另外我们把有权访问私有变量和私有函数的公有方法称为特权方法。如:

function MyObject(){
    var privateVariable = 10;
    function privateFunction(){
        return false;
    }
    this.publicMethod = function(){
        privateVariable ++;
        return privateFunction();
    };
}    
var x = new MyObject();
console.log(x.publicMethod()) ;//false

利用私有和特权成员,可以隐藏那些不应该被直接修改的数据。如:

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

var person = new Person("Oliver");
console.log(person.getName());
person.setName("Oli"); //Oliver
console.log(person.getName()); //Oli

静态私有变量

私有作用域中定义私有变量和函数,同样也可以创建特权方法,如:

(function(){
    var privateValue = 10;
    function privateFunction(){
        return false;
    }
    
    MyObject = function(){}; //没有var 属于全局变量,严格模式下会报错
    
    MyObject.prototype.publicMethod = function(){
        privateValue ++;
        return privateFunction();
    };
})();

var instance = new MyObject();
console.log(instance.publicMethod()); //false

模块模式

针对单例创建私有变量和特权方法。单例就是只有一个实例的对象。如:

var singleton = {
    name: value,
    method: function(){
        
    }
};

添加私有变量以及特权方法:

var singleton = function(){
    var privateVariable = 10;
    
    function privateFunction(){
        return false;
    }
    
    return {
        publicProperty: true,
        publicMethod: function(){
            privateVariable++;
            privateFunction();
        }
    };
}();

简化:

var a = function(){
    var x;
    function y(){};
    return {
        z1,
        z2
    };
}();

增强的模块模式

这种模式适合那些单例必须是某种类型的实例。如:

var singleton = function(){
    var privateVariable = 10;
    
    function privateFunction(){
        return false;
    }
    
    var object = new CustomType();
    
    object.publicProperty = true;
    
    object.publicMethod = function(){
        privateVariable++;
        return privateFunction();
    };
    return object;
}();

JS菌
6.4k 声望2k 粉丝