JS:模仿块级作用域及私有变量
来源:互联网 发布:js设置css样式display 编辑:程序博客网 时间:2024/05/16 05:29
模仿块级作用域
JavaScript没有块级作用域
例如:
function outputNumber(){ for(var i = 0;i<count;i++){ alert(i); } alert(i);}
函数中定了一个for循环,在Java,C++等语言中,变量i只在for循环语句中有定义,循环一旦结束,变量就会被销毁。可是在JavaScript中,变量i是定义在outputNumber()活动对象中的,因此,从它有定义开始,就可以在函数内部随处访问它。即使像下面这样错误的重新声明同一个变量,也不会改变它的值。
function outputNumbers(count){ for(var i = 0;i<count;i++){ console.log(i); } var i; alert(i);//5 } outputNumbers(5)
JS从来不会告诉你是否多次声明了同一个变量;遇到这种情况,它只会对后续的声明视而不见(但是如果对i进行重新赋值,i的值会发生变化)。匿名函数可以用来模仿块级作用域并且避免这个问题。
用作块级作用域的(通常称为私有作用域)的匿名函数的语法如下所示:
(function(){ //这里是块级作用域})();
无论在什么地方,只要临时需要一些变量,就可以使用私有作用域,例如将上文中提到的代码修改为:
function outputNumbers(count){ (function(){ for(var i = 0;i<count;i++){ console.log(i); } })(); console.log(i);// i is not defined at outputNumbers } outputNumbers(5)
在这个重写的函数内部,我们在for循环外部插入了有个私有作用域。在匿名函数中定义的任何变量,都会在执行结束的时候销毁。因此变量i只能在循环内部引用,不能再for循环外部引用,使用之后立即被销毁。而私有作用域能够访问变量count,是因为这是一个匿名函数闭包,它能够访问包含作用域中的所有变量。
这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。要做到尽量少向全局作用域中添加变量和函数。在一个有多人共同参与开发的项目中,过多的全局变量可能会导致命名冲突。通过创建私有变量作用域可以解决这个问题:
例如:
(function(){ var now = new Date(); if(now.getMoth() == 0&&now.getDate() == 1){ alert("Haapy new year!"); } })();
在新年的时候向用户发送新年祝福,其中变量now现在是匿名函数中的局部变量,而我们不必在全局作用域中创建它。
私有变量
在任何函数中定义的变量都可以认为是私有变量,因为不能再函数外部访问这些变量,私有变量包括函数参数,局部变量和函数内部定义的其他函数。
我们可以在函数内部创建一个闭包,那么我们就可以通过闭包函数的作用域链访问这些私有变量。利用这一点我们就可以创建用于访问私有变量的公有方法。
例如:
function MyObject(){ //私有变量和私有函数 var privateVariable = 10; function privateFunction(){ return false; } //特权方法 this.publicMethod = function(){ privateVariable++; return privateFunction(); } }
这个模式在构造函数内部定义了所有私有变量和函数,然后又继续创建了能够访问这些私有成员的特权方法。在构造函数中定义特权方法,特权方法作为闭包有权访问在构造函数中定义的所有变量和函数。对于这个例子而言,变量privateVariable和函数privateFunction()只能通过特权方法publicMethod()来访问。
利用私有成员和特权成员,可以隐藏那些不应该直接被修改的数据,例如:
function Person(name){ this.getName = function(){ return name; }; this.setName = function(value){ name = value; }; } var person3 = new Person("Bob"); alert(person3.getName());//Bob var person4 = new Person("Marry"); alert(person4.getName());//Marry
以上构造函数中定义了两个特权方法:getName()和setName()。这两个函数都可以在构造函数外部使用,而且有权访问到私有变量name。在Person构造函数外部没有任何方法可以访问到这个变量,但是特权方法作为闭包可以通过其作用域链访问到这个变量。私有变量在Person的每一个实例都不同,因为每次调用构造函数都会重新创建这两个方法。
静态私有变量
通过在私有作用域中定义私有变量或函数,同样也可以创建特权方法,其基本模式如下:
(function(){ //私有变量和私有函数 var privateVariable = 10; function privateFunction(){ return false; } //构造函数 MyObject = function(){};//没有使用var 声明,可以在全局执行环境中访问到 //公有/特权方法 MyObject.prototype.publicMethod = function(){ privateVariable++; return privateFunction(); };})();
这个模式与构造函数中定义的特权方法的主要区别在于:
私有变量和函数是由实例所共享的,即私有作用域中的privateVariable和函数privateFunction()是由所有实例所共享的。
下面举例具体说明:
(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("Bob"); alert(person1.getName());//Bob var person2 = new Person("Marry"); alert(person1.getName());//Marry alert(person2.getName());//Marry
这里的name变成了一个静态的由所有实例共享的属性。
具体分析:当实例化对象person2时,传入的value的值为”Marry”,value的值被赋给name,这是实例person1调用此方法输出的是name的值,此时name的值已经被修改为”Marry”,所以说name是一个在匿名函数私有变量作用域内部,被所有实例所共享的属性。
- JS:模仿块级作用域及私有变量
- js私有作用域(function(){})(); 模仿块级作用域
- JavaScript模仿块级作用域与私有变量
- 《JS高程(3)》闭包/模仿块级作用域/私有变量-第7章笔记(05)
- 第七章:函数表达式(模仿块级作用域和私有变量)
- 块级作用域和私有变量
- JS 模仿块级作用域
- JS的模仿块级作用域
- js中模仿块级作用域
- js中的作用域及私有变量
- js闭包实现块级作用域和私有变量的访问
- 模仿块级作用域
- JavaScript闭包-块级作用域和私有变量
- JavaScript中的块级作用域和私有变量
- JavaScript中的块级作用域和私有变量
- 块作用域和私有变量
- javascirpt如何模仿块级作用域(js高程笔记)
- Javascript中模仿块级作用域
- 第842期机器学习日报(2017-01-07)
- Mysql命令
- 第847期机器学习日报(2017-01-12)
- 第850期机器学习日报(2017-01-15)
- 第846期机器学习日报(2017-01-11)
- JS:模仿块级作用域及私有变量
- spring boot实现上传图片并在页面上显示
- Vmware虚拟机下三种网络模式配置
- STL练习: queue ——队列
- 第844期机器学习日报(2017-01-09)
- 第853期机器学习日报(2017-01-18)
- 第852期机器学习日报(2017-01-17)
- 第854期机器学习日报(2017-01-19)
- systemctl设置svn开机启动以及service文件的写法