Javascript 私有变量
2015-08-14 11:45
633 查看
转自Javascript高级程序设计(第三版):
任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量。私有变量包括函数的参数,局部变量以及在函数内部定义的其他函数。
如果在函数内部创建一个闭包,那么闭包可以通过自己的作用域链访问这些变量。而利用这一点,就可以创建用于访问私有变量的公有方法。
我们把有权访问私有变量和私有函数的公有方法称为特权方法。有两种在对象中创建特权方法的方式。
1)))第一种是在构造函数中定义特权方法,基本模式如下:
Tip:关于javaScript构造函数的简介:JavaScript构造函数
在创建MyObject的实例后,除了使用publicMethod()这一个途径外,没有其他办法可以访问privateVariable和privateFunction();
利用私有和特权成员,可以隐藏那些不应该被直接修改的数据。例如:
私有变量name在Person的每一个实例中都不相同,因为每次调用构造函数都会重新创建这两个方法。
2)))通过在私有作用域中定义私有变量和函数,同样可以创建特权方法。为了不用在每一个实例中都重新创建私有变量和私有方法,可以采用原型模式。
我们先来简单的了解一下什么是原型:
我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。如下面例子所示:
接下来我们看一下通过静态私有变量创建特权方法的基本模式:
首先,公有方法是在原型上定义的,这一点体现了典型的原型模式。同时,我们在声明MyObject的时候没有使用var关键字。记住:未经声明的变量,总是会创建一个全局变量。因此,MyObject就成了一个全局变量,能够在私有作用域之外被访问到。但是,在严格模式下,给未经声明的变量赋值会导致错误。
这个模式与在构造函数中定义特权方法的主要区别,就在于私有变量和函数是由实例共享的。由于特权方法是在原型上定义的,因此所有实例都使用一个函数。而这个特权方法,作为一个闭包,总是包含着对作用域的引用。
在这种模式下,变量name就变成了一个静态的,由所有实例共享的属性。结果就是所有的实例会返回相同的值。
3)))模块模式
单例模式
所谓单例(singleton),指的就是只有一个实例的对象。按照惯例,Javascript是以对象字面量的方式来创建单例对象的。
模块模式通过为单例添加私有变量和特权方法能够使其得到增强。
由于这个对象是在匿名函数内部定义的,因此它的公有方法有权访问私有变量和函数。
这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和(或)方法对其加以增强的情况。
总结:
1)函数表达式不同于函数声明。函数声明要求有名字,但函数表达式不需要。没有名字的函数表达式也叫做匿名函数。
2)在无法确定如何引用函数的情况下,递归函数就会变得特别复杂。
3)递归函数应该始终使用arguments.callee来递归地调用自身,不要使用函数名,函数名可能会发生变化。
4)在后台执行环境中,闭包的作用链包含着它自己的作用域,包含函数的作用域和全局作用域。
5)通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。
6)但是,当函数返回了一个闭包时,这个函数的作用域将会在内存中一直保存到闭包不存在为止。
7)即使javascript中没有正式的私有属性的概念,但是可以使用闭包来实现公有方法,而通过公有方法可以访问包含在作用域中定义的变量。
8)有权访问私有变量的公有方法叫做特权方法。
9)可以使用构造函数,原型模式来实现自定义类型的特权方法,也可以使用模块模式,增强的模块模式来实现单例的特权方法。
任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量。私有变量包括函数的参数,局部变量以及在函数内部定义的其他函数。
如果在函数内部创建一个闭包,那么闭包可以通过自己的作用域链访问这些变量。而利用这一点,就可以创建用于访问私有变量的公有方法。
我们把有权访问私有变量和私有函数的公有方法称为特权方法。有两种在对象中创建特权方法的方式。
1)))第一种是在构造函数中定义特权方法,基本模式如下:
function MyObject(){ //私有变量和私有函数 var privateVariable =10; function privateFunction(){ return false; } //特权函数 this.publicMethod = function(){ privateVariable++; return privateFunction(); }; }
Tip:关于javaScript构造函数的简介:JavaScript构造函数
在创建MyObject的实例后,除了使用publicMethod()这一个途径外,没有其他办法可以访问privateVariable和privateFunction();
利用私有和特权成员,可以隐藏那些不应该被直接修改的数据。例如:
function Person(name){ this.getName=function(){ return name; } this.setName=function(value){ name=value; } } var person=new Person("Nicholas"); alert(person.getName()); person.setName("Greg"); alert(person.getName());
私有变量name在Person的每一个实例中都不相同,因为每次调用构造函数都会重新创建这两个方法。
2)))通过在私有作用域中定义私有变量和函数,同样可以创建特权方法。为了不用在每一个实例中都重新创建私有变量和私有方法,可以采用原型模式。
我们先来简单的了解一下什么是原型:
我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。如下面例子所示:
function Person(){ } Person.prototype.name="Nicholas"; Person.prototype.age=29; Person.prototype.job="Software Engineering"; Person.prototype.sayName=function(){ return this.name; }; var person1=new Person(); alert(person1.sayName()); var person2=new Person(); alert(person2.sayName()); alert(person1.sayName()==person2.sayName());
接下来我们看一下通过静态私有变量创建特权方法的基本模式:
(function(){ var privateVariale = 10; function privateFunction(){ return false; } MyObject = function(){ }; MyObject.prototype.publicMethod = function(){ privateVariale++; privateFunction(); } })();
首先,公有方法是在原型上定义的,这一点体现了典型的原型模式。同时,我们在声明MyObject的时候没有使用var关键字。记住:未经声明的变量,总是会创建一个全局变量。因此,MyObject就成了一个全局变量,能够在私有作用域之外被访问到。但是,在严格模式下,给未经声明的变量赋值会导致错误。
这个模式与在构造函数中定义特权方法的主要区别,就在于私有变量和函数是由实例共享的。由于特权方法是在原型上定义的,因此所有实例都使用一个函数。而这个特权方法,作为一个闭包,总是包含着对作用域的引用。
(function(){ var name = ""; Person = function(value){ name=value; }; Person.prototype.getName = function(){ return name; }; Person.prototype.setName = function(value){ name=value; }; })(); var person1 = new Person("Nocholas"); alert(person1.getName());//Nocholas person1.setName("Greg"); alert(person1.getName());//Greg var person2 = new Person("Michale"); alert(person1.getName());//Michale alert(person2.getName());//Michale
在这种模式下,变量name就变成了一个静态的,由所有实例共享的属性。结果就是所有的实例会返回相同的值。
3)))模块模式
单例模式
所谓单例(singleton),指的就是只有一个实例的对象。按照惯例,Javascript是以对象字面量的方式来创建单例对象的。
var singleton={ name:value; method:function(){ //这是方法的代码 }; };
模块模式通过为单例添加私有变量和特权方法能够使其得到增强。
var singleton={ //私有变量和私有函数 var privateVariable = 10; function privateFunction(){ return false; } //特权/公有方法和属性 return{ publicProperty:true; publicMethod:function(){ privateVariable++; privateFunction(); } } };
由于这个对象是在匿名函数内部定义的,因此它的公有方法有权访问私有变量和函数。
var application = function(){ //私有变量和函数 var components = new Array(); //初始化 components.push(new BaseComponent()); //公共 return{ getComponentCount:function(){ return components.length; }, registerComponent:function(component){ if(typeof component =="object"){ component.push(component); } } }; }();4)))增强的模块模式
这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和(或)方法对其加以增强的情况。
var singleton = function(){ //私有变量和私有函数 var privateVariable = 10; function privateFunction(){ return false; } //创建对象 var object = new customeType(); //添加公有属性和方法 object.publicProperty = true; object.publicMethod = function(){ privateVariable++; privateFunction(); }; //返回这个对象 return object; }
总结:
1)函数表达式不同于函数声明。函数声明要求有名字,但函数表达式不需要。没有名字的函数表达式也叫做匿名函数。
2)在无法确定如何引用函数的情况下,递归函数就会变得特别复杂。
3)递归函数应该始终使用arguments.callee来递归地调用自身,不要使用函数名,函数名可能会发生变化。
4)在后台执行环境中,闭包的作用链包含着它自己的作用域,包含函数的作用域和全局作用域。
5)通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。
6)但是,当函数返回了一个闭包时,这个函数的作用域将会在内存中一直保存到闭包不存在为止。
7)即使javascript中没有正式的私有属性的概念,但是可以使用闭包来实现公有方法,而通过公有方法可以访问包含在作用域中定义的变量。
8)有权访问私有变量的公有方法叫做特权方法。
9)可以使用构造函数,原型模式来实现自定义类型的特权方法,也可以使用模块模式,增强的模块模式来实现单例的特权方法。
相关文章推荐
- js设计模式
- webuploader+springmvc实现多文件上传(html+js+css原创,后台代码借鉴)
- JS键盘Enter事件
- 深入理解Javascript变量作用域
- JavaScript实现给按钮加上双重动作的方法
- createjs初学-关于Ticker
- you think you know javascript?
- 新浪微博SDK抛出异常-[__NSDictionaryM weibosdk_WBSDKJSONString]: unrecognized selector sent to instance 0x7fb
- String,Json,Map之间的转化
- Html页面操作json串
- 前后端JSON传递
- Javascript原型模式总结梳理
- .net序列化和反系列化json与类型对象转换
- eclipse下如何直接做JSP代码设计
- js中(function(){…})()立即执行函数写法理解
- JavaScript读写Cookie
- js实现Select列表各项上移和下移的方法
- BSON与JSON的区别
- JSON数组排序
- 前台 JSON对象转换成字符串 相互转换 的几种方式