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. 前端开发 Vue -2npm

    npm介绍 说明:npm(node package manager)是nodejs的包管理器,用于node插件管理(包括安装.卸载.管理依赖等) 使用npm安装插件:命令提示符执行npm instal ...

  2. Python笔记-备忘

    一.向列表添加元素 x.append(y) #末尾添加一个元素 x.extend([y,z]) #末尾添加多个元素 x.insert(index,y) 二.向列表获取元素 x[index] 三.从列表 ...

  3. Genymotion上运行ARM架构Android项目

    问题 Genymotion是x86的模拟器,在集成一些第三方的SDK时需要添加一些放在armeabi.armeabi-64文件夹下面的.so文件,这些文件在arm架构下才能运行.这时模拟器就不能用了. ...

  4. SAP Cloud Platform上Destination属性为odata_gen的具体用途

    今天工作发现,SAP Cloud Platform上创建Destination维护的WebIDEUsage属性很有讲究: 帮助文档:https://help.sap.com/viewer/825270 ...

  5. 解决sqoop抽数报错:IO Error: Connection reset

    遇到的问题:进行sqoop抽数时,虽然能成功执行,但是过程中有很多这样的信息 19/11/20 15:17:11 INFO mapreduce.Job: Task Id : attempt_15737 ...

  6. go语言的duck typing

    对于一个接口来讲有:实现者和使用者. 传统的面向对象都是实现者实现接口,然后告诉大家接口规范(传餐和返回):而golang比较特别,是使用者们去分别实现符合自己需求的各自的接口方法的.而C++是实现者 ...

  7. 【2017-11-26】Linq表连接查询

    class Program { static void Main(string[] args) { //Linq创建的数据库上下文对象db DataClasses2DataContext db = n ...

  8. springboot集成Apollo分布式配置

    安装Apollo服务 1.安装mysql 地址:https://www.cnblogs.com/xuaa/p/10782352.html 2.下载Apollo源码到本地 地址:https://gith ...

  9. springboot @value 注解的使用

    1,通过@value来注入对应的值,直接在字段上添加@value 获取application.properties文件中的值. @Configuration public class DemoConf ...

  10. 线程的 run()和 start()有什么区别?(未完成)

    线程的 run()和 start()有什么区别?(未完成)