1块级作用域
js 将 function 关键字当作一个函数声明的开始,而函数声明后面不能跟圆括号,然而,函数表达式的后边可以跟圆括号。
//错误的写法
function myFunc() {
/*....*/
}()
function () {
/*....*/
}
//正确的写法
(function myFun(){
/*....*/
})();
(function (){
/*...*/
})();
var app = function() {
/*....*/
}();
这种函数自调用的方法,经常在全局作用域中被用在函数外部,从而限制向全局作用域添加过多的变量和函数。
2 私有变量
在构造函数的内部使用闭包创建私有变量。
function Person(name) {
this.getName = function() {
return name;
}
this.setName = funtion(value) {
name = value;
}
}
//或者
function Person () {
var age = 10;
function sayHello = function() {
console.log("1111");
}
this.publicMethod = function() {
age++;
return sayHello();
}
}
由于这两个方法都是挂载在this上的,所以对于每个实例,它们的私有变量都不相同,因为每次构造函数都会重新创建这些方法,这样做的缺点就是,你必须为每个实例构造同样一组新方法。
改进的方法:使用原型的方法在构造函数的原型上创建方法,这样所有的实例都公用一个方法。
function Person () {
var age = 10;
function sayHello = function() {
console.log("1111");
}
Person.prototype.publicMethod = function() {
age++;
return sayHello();
}
}
3 静态私有变量
借助函数自调用和函数表达式的特点,但是创建的所有实例都公用一个实例变量,每个实例都没有自己的私有变量。
(function(){
var name = "";
//在window上添加了一个Person的构造函数
Person = function(value) {
name = value;
};
Person.prototype.getName = function(){
return name;
}
Person.prototype.setName = function(value){
name = value;
}
})();
var person1 = new Person("zsk");
console.log("person1",person1.getName());
var person2 = new Person("hz");
console.log("person2",person2.getName());
console.log("person1",person1.getName());
运行结果
应用场景:
4 模块模式
单例模式的实现方式:js是以对象字面量的方式来创建单例对象的。
最简单的单例模式
var singleTon = {
name: "zsk",
method: function(){
}
};
添加私有变量和特权方法,借助 一个返回对象的匿名函数。
var singleTonEnhance1 = function () {
var name = "";
funtion doSomething(){
console.log(111);
}
return {
name: name,
doSomething: doSomething
};
}();
增强的模块模式(适合某些单例必须是某种类型的单例)
var singleTonEnhanced2 = function(){
var privateValiable = 10;
var obj = new CustomeType();
obj.sayName = function(){};
}();