转自Javascript高级程序设计(第三版):

任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量。私有变量包括函数的参数,局部变量以及在函数内部定义的其他函数。

如果在函数内部创建一个闭包,那么闭包可以通过自己的作用域链访问这些变量。而利用这一点,就可以创建用于访问私有变量的公有方法。

我们把有权访问私有变量和私有函数的公有方法称为特权方法。有两种在对象中创建特权方法的方式。

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)可以使用构造函数,原型模式来实现自定义类型的特权方法,也可以使用模块模式,增强的模块模式来实现单例的特权方法。

Javascript 私有变量相关推荐

  1. javascript入门之私有变量

    开始接触这门语言时,可能都会觉得这门语言缺少访问控制符(如public.private.protected),从而导致 不能定义私有变量和私有方法.但经过进一步了解就会知道javascript同样可以 ...

  2. ​JavaScript私有属性的多种实现方式总汇

    来源 | http://www.fly63.com JavaScript被很多人认为并不是一种面向对象语言,原因有很多种,比如JavaScript没有类,不能提供传统的类式继承:再比如JavaScri ...

  3. ES6系列之私有变量的实现

    2019独角兽企业重金招聘Python工程师标准>>> 前言 在阅读 <ECMAScript 6 入门>的时候,零散的看到有私有变量的实现,所以在此总结一篇. 1. 约定 ...

  4. python私有变量和继承_python私有变量子类如何继承-女性时尚流行美容健康娱乐mv-ida网...

    女性时尚流行美容健康娱乐mv-ida网 mvida时尚娱乐网 首页 美容 护肤 化妆技巧 发型 服饰 健康 情感 美体 美食 娱乐 明星八卦 首页  > 高级搜索 浅谈 python 中的 私有 ...

  5. 深入理解JavaScript的变量作用域

    在学习JavaScript的变量作用域之前,我们应当明确几点: a.JavaScript的变量作用域是基于其特有的作用域链的. b.JavaScript没有块级作用域. c.函数中声明的变量在整个函数 ...

  6. es5 温故而知新 创建私有成员、私有变量、特权变量的方法

    其实js是不支持私有变量的.哪怕到es6的class语法.虽然有许多变相的方式.但非常冗余而不推崇. 这里介绍的实际上也不是class语法,而是普通的函数,并且利用IIFE(闭包)的方式来实现私有. ...

  7. python定义私有变量的方法_Python怎么修改私有属性 如何访问python类中的私有方法...

    python 类为什么不能定义私有属性和方法 因为b.name[0] = 'zhang'修改的是类属性,类属性是全局的,所有的实例共享,如果想私有化,可以添加 def __init__( self ) ...

  8. Object-C 有私有变量?私有方法?

    从object-c 动态编译机制上讲是不存在私有变量和私有方法的.但是如果你不在.h中声明变量和方法在其它地方无法访问这些变量和方法,那么就成了私有的了.私有变量也可以使用@prviter进行修饰. ...

  9. Java私有变量是否可继承

    Java 父类中权限为private的私有变量,子类对象继承后,在其内存中其实也有该变量存在,只是不能直接引用该变量,而是需要通过调用父类public或protected的set或get等方法使用该变 ...

最新文章

  1. 2021年大数据HBase(十四):HBase的原理及其相关的工作机制
  2. 字符串反序,逆序输出字符串
  3. 图论:Dinic算法
  4. Liferay门户与CAS实现SSO单点登录
  5. [转]《吐血整理》系列-顶级程序员工具集
  6. python计算公式分母有0_你知道Python中的浮点除法和积分除法吗,python,float,整除,都...
  7. 【Materials Studio学习七】构建石墨烯
  8. delphi开发小白盒接口实现扫码控制
  9. 手机快播安卓版 Qvod player V1.0.19
  10. 笔记本电脑ip服务器未运行怎么办,如何解决控制台打开(Pubwin)提示“服务器未启动或服务器IP地址已更改”的问题...
  11. 论文笔记(十六):Learning to Walk in Minutes Using Massively Parallel Deep Reinforcement Learning
  12. 华为P20 Pro对比iPhone X:谁更能拍出人像高级美?
  13. 全息投影是计算机技术吗,全息投影、VR技术、AR增强现实技术的区别
  14. Bearer token
  15. Python 带你走进哈利波特的魔法世界
  16. ​想聊天?自己搭建个聊天机器人吧!
  17. crmeb 小程序包大小超过2M的解决方法
  18. buildroot+qt+qcamrea+opencv打开摄像头进行拍照录像保存功能
  19. 编写AIC工艺参数计算Matlab程序(疯狂踩坑)
  20. 计算机毕业设计Java化妆品销售网站

热门文章

  1. Java基础学习第二讲:Java数据类型,变量及常量
  2. 近红外荧光ICG-whey protein 吲哚菁绿标记乳清蛋白
  3. 网络渗透测试漏洞复现任务
  4. SWF文件格式说明书--SWF文件结构
  5. mysql行转列 -夜幕思年华
  6. 蓝桥杯算法训练VIP-旅行家的预算
  7. Android窗口机制:六、一定要在主线程才可以更新UI吗?为什么?(源码版本SDK31)
  8. 光电技术与光纤基础期末复习笔记
  9. 图像增强及运算篇之图像掩膜直方图和HS直方图
  10. 超级计算机预测巴萨,懂球帝晚报:超级计算机预测曼联、阿森纳无缘欧战;佩雷斯回应加盟巴萨传闻...