Javascript--闭包一节中我们讲解了闭包的作用域和作用域链的特性。了解到在外部一般是不可能访问到内部作用域中的变量的,然而通过闭包我们可以定义特权方法访问私有变量。下面先介绍块级作用域再介绍几种特权方法。

一、模仿块级作用域

Javascript是没有块级作用域的概念的。所以我们在语句块中定义的变量,其作用域是包含函数而非语句块。

function outPut(count){
for(var j=0;j<count;j++){
alert(j);
}
alert(j); //计数
}

在Java、C++语句中,变量j在循环语句结束后就销毁了。但再Javascript中,变量j则是函数outPut的变量。因此我们通过函数表达式的变式来模仿块级作用域。

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

这个时候变量j只在私有作用域中有效,运行结束就销毁。这种技术经常在全局作用域中被用在函数外部,从而限制向全局环境中添加过多变量、函数。

二、构造函数访问法

现在我们介绍第一种访问私有变量的方法--构造函数法。私有变量指在函数内部中定义的变量、参数及其它函数。

function Person(name){
var name=name;
this.sayName=function(){
alert(name);
}
};
var person1=new Person("Bob");
var person2=new Person("Mike");
person1.sayName(); //Bob
person2.sayName(); //Mike

sayName()方法就是Person所有实例的一个特权方法。但有个问题:

alert(person1.sayName==person2.sayName);    //false

每个实例的同名特权方法都要重新创建。

三、借用原型访问

function Person(name){
var name=name;
Person.prototype.sayName=function(){
alert(name);
}
};
var person1=new Person("Bob");
person1.sayName(); //Bob
var person2=new Person("Mike");
person1.sayName(); //Mike
person2.sayName(); //Mike
alert(person1.sayName==person2.sayName); //true

这种方法每个实例的特权方法都是动态共享的。但每个实例都没有自己的私有变量。

四、组合访问

function Person(name){
var name=name;
Person.prototype.sayName=function(){
alert(name);
};
this.sayPrivateName=function(){
alert(name);
}
};

将两种方式融合,看看其访问私有变量的效果:

var person1=new Person("Bob");
person1.sayName(); //Bob
person1.sayPrivateName(); //Bob
var person2=new Person("Mike");
person1.sayName(); //Mike
person1.sayPrivateName(); //Bob
person2.sayName(); //Mike
alert(person1.sayName==person2.sayName); //true
alert(person1.sayPrivateName==person2.sayPrivateName); //false

私有变量若痛过原型方法访问,私有变量就是动态共享的;若通过实例方法访问,私有变量在每个实例中都有其特异性。而实例属性不同,实例属性将覆盖同名原型属性,且永远是特异性的。

五、模块模式

前面的方法都是为自定义类型创建特权方法,而模块模式是为单例创建特权方法。

var person=function(){
var name="Bob"; //私有变量
function privateFunction(){ //私有函数
alert(true);
}; return {
publicName:name, //特权属性
publicMethod:function(){ //特权方法
return privateFunction();
}
}
}();
alert(person.publicName);    //Bob
person.publicMethod(); //true

简言之,如果必须创建一个对象并对其进行初始化,且还要公开一些能够访问这些私有变量的方法,那么就可以使用模块模式。

javascript--特权方法的更多相关文章

  1. JavaScript【面向对象】-静态方法-私有方法-公有方法-特权方法

    JavaScript面向对象是近年来比较火的一个概念了,由于小弟才疏学浅,虽然做过不少的web项目,看了网上很多深奥的资料和教程,还是对他们深奥 的理论一知半解,前段时间看了点书,总算有了自己的理解, ...

  2. JavaScript 执行环境(执行上下文) 变量对象 作用域链 上下文 块级作用域 私有变量和特权方法

    总结自<高程三>第四章  理解Javascript_12_执行模型浅析   JS的执行环境与作用域  javascript高级程序第三版学习笔记[执行环境.作用域] 在javascript ...

  3. Javascript 面向对象(共有方法,私有方法,特权方法,静态属性和方法,静态类)示例讲解

    一,私有属性和方法 私有方法:私有方法本身是可以访问类内部的所有属性(即私有属性和公有属性),但是私有方法是不可以在类的外部被调用. <script> /* * 私有方法:私有方法本身是可 ...

  4. 第七章 函数表达式和函数声明,关于this对象 ,私有作用域(function(){})() ,私有变量和特权方法

    一:函数表达式和函数声明 1:函数声明和函数表达式的区别 ①函数声明不需要分号结尾 ②函数声明有函数提升的特点 ③函数声明后面不能跟圆括号直接调用,因为javascript将function关键字当作 ...

  5. JavaScript - reduce方法,reduceRight方法 (Array)

    JavaScript - reduce方法 (Array) 解释:reduce() 方法接收一个函数作为累加器(accumulator),数组 中的每个值(从左到右)开始合并,最终为一个值. 语法:a ...

  6. JavaScript slice() 方法

    JavaScript slice() 方法  JavaScript Array 对象 实例 在数组中读取元素: var fruits = ["Banana", "Oran ...

  7. JavaScript toLocaleString() 方法

    JavaScript toLocaleString() 方法 JavaScript Array 对象 定义和用法 把数组转换为本地字符串. 语法 arrayObject.toLocaleString( ...

  8. 关于JavaScript lastIndexOf() 方法 w3school.com.cn写的不一定全对

    关于JavaScript lastIndexOf() 方法 w3school.com.cn的表述是 定义和用法 lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的 ...

  9. javascript一些方法兼容

    javascript一些方法兼容 标签(空格分隔): javascript 方法收集 [TOC] Object.keys 参考地址 if (!Object.keys) Object.keys = fu ...

  10. 在Swift中使用JavaScript的方法和技巧

    本文作者Nate Cook是一位独立的Web及移动应用开发者,是继Mattt大神之后NSHipster的主要维护者,也是非常知名活跃的Swift博主,并且还是支持自动生成Swift在线文档的Swift ...

随机推荐

  1. qt连接oracle数据库

    由与qt开源版本没有提供oracle数据库驱动,需要自己根据源代码来手动编译oracle驱动. 经过近三天的折腾,终于成功编译oracle驱动,连接到数据库 ps:期间经过各种失败疼苦迷茫.现在终于完 ...

  2. datagrid行内编辑

    编辑属性 :editor: { type: 'text'} $('#listShow').datagrid({ height : 478, pagesize : 20, pageList : [20, ...

  3. vue + element-ui 国际化实现

    1. 安装组件和插件 cnpm i element-ui -S // 安装elementcnpm i vue-i18n -S //安装i18n 2.将国际化资源放在assets目录下 3.在src下新 ...

  4. Unable to open nested entry '********.jar' 问题解决

    今天把现网版本的task的jar拖回来然后用7-zip打开拖了一个jar进去替换mysql-connector-java-5.1.47.jar  为  mysql-connector-java-5.1 ...

  5. CAD二次开发之入门坑

    如果没有引用第一个dll,则会报未找到引用CommandMethod

  6. 当SAP云平台account的service Marke place里找不到Machine Learning服务该怎么办

    问题症状: 我在CloudFoundry环境的Service Market place里根本找不到Leonardo ML foundation这组服务. 解决方案: 进入global Account- ...

  7. 使用Mmap系统调用进行硬件地址访问

    Mmap系统调用: Mmap函数是内存映射函数,负责把文件内容映射到进程的虚拟内存空间,通过对这段内存的读取和修改,来实现堆文件的读取和修改,而不需要再调用read,write等操作. 原型如下: 其 ...

  8. 超详细的Java面试题总结之JavaWeb基础知识总结

    ervlet总结: 在Java Web程序中,Servlet主要负责接收用户请求HttpServletRequest,在doGet(),doPost()中做相应的处理,并将回应HttpServletR ...

  9. idou老师教你学Istio 08: 调用链埋点是否真的“零修改”?

    本文将结合一个具体例子中的细节详细描述Istio调用链的原理和使用方式.并基于Istio中埋点的原理解释来说明:为了输出一个质量良好的调用链,业务程序需根据自身特点做适当的修改,即并非官方一直在说的完 ...

  10. 洛谷P5002 专心OI - 找祖先

    题目概括 题目描述 这个游戏会给出你一棵树,这棵树有\(N\)个节点,根结点是\(R\),系统会选中\(M\)个点\(P_1,P_2...P_M\). 要Imakf回答有多少组点对\((u_i,v_i ...