您的位置:首页 > Web前端 > JavaScript

js中的信息隐藏——封装

2016-04-05 17:18 796 查看
其中部分示例代码来源于《JavaScript设计模式》一书

封装的主要目的就是将部分变量和函数隐藏起来,只让使用者看到想让他们看到的东西,而隐藏起来不想让他们看到的东西。这样做有以下好处:

防止他们对这些东西进行误操作。
减弱类与类之间的耦合性,增强各个模块、各个类的独立性,从而便于对类的修改和替换。

最简单的封装举例

不隐藏信息的类的定义:

function foo() {
this.a = 10;
}

foo.prototype.bar= function() {
this.a *= 2;
}


这时我们是可以通过foo.a来访问变量a的。

隐藏信息的类的定义:

function foo() {
var a = 10;

function bar() {
a *= 2;
return a;
}
return bar;
}

var baz = foo();
baz();//return 20
baz();//return 40
baz();//return 80

var blat = foo();
blat();//return 20

在这里我们并不能通过foo.a访问a,因为a并不是foo的属性,只是在该函数作用域内声明的一个局部变量。而当我们调用bar函数时,该函数并非运行在其调用时所在作用域,而是运行在定义bar函数的作用域处,即a所在作用域,故bar函数作为foo的子函数,可以访问其父函数中的变量,并且不同的实例化对象,各自有一个作用域和变量和子函数的副本,不同实例中的变量值无关。总结而言

将想隐藏的信息使用var声明而非使用this.变量名声明。
通过定义子函数调用想隐藏的信息(这种用来访问私有变量的函数,又称为特权函数)。
不同实例化对象有着不同的作用域、子函数、变量的副本。

封装中的静态方法和属性

所谓静态方法和属性,便是该类对象所共有的一个方法和属性,不随着实例化对象的增加而增加,所有该类对象公用这一个方法或属性。将函数和属性定义为静态的原因:

避免副本所占用的空间。从上面的介绍中我们知道,每实例化一个对象,就会新产生一个作用域、属性以及子函数的副本。为了减少副本占用空间,可以将部分变量变为所有实例对象公用的静态变量。
跟踪构造器的调用情况

举个栗子:
var foo_object = (function foo() {
var numberOfFoo = 10;//私有静态属性

return function bar(a_value) {/*通过返回构造函数,foo_object被赋值为该构造函数。
每次实例化该类对象,只是产生该构造函数作用域和该作用域下定义的变量和函数*/
var a = 10;//私有非静态属性
a = 2 * a * a_value;
numberOfFoo++;
if (numberOfFoo > 50)
throw new Error('Only 50 instances of foo can be created');//通过静态变量控制类被实例化的次数。
}

})();
var obj1 = foo_object(1);//numberOfFoo=1  a=20
var obj2 = foo_object(3);//numberOfFoo=2  a=60


对于静态变量,很简单,你想让该类下的实例化对象公用该变量,就将该变量定义为静态变量。

对于静态函数,还要考虑一点,由上面的例子可见,若定义静态函数,则该函数将被定义在构造函数之外,那么该函数也就无法调用构造函数中的私有变量了。因此

只有当你不需要使用该函数访问非静态私有变量时,你才应该考虑将函数定义为静态函数。

私有静态常量

即定义一个赋予初值的静态变量,为该变量只定义取值的函数,而不定义改变量值得函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: