明白javascript封装
封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏。通过封装可以强制实施信息隐藏。
在JavaScript中,并没有显示的声明私有成员的关键字等。所以要想实现封装/信息隐藏就需要从另外的思路出发。我们可以使用闭包的概念来创建只允许从对象内部访问的方法和属性,来达到封装的要求。
基本方式
一般来说,我们学用的有三种方法来达到封装的目的。
使用来声明一个变量,然后再声明getXXX、setXXX等取值、赋值的方法。
使用this._XXX来声明一个变量,然后再声明getXXX、setXXX等取值、赋值的方法。
利用“函数作用域”这一个概念来做。
1. 门户大开型
var Book = function(isbn,title,author){ sbn(isbn); itle(title); uthor(author); }; otype = { setIsbn: function(isbn){ = isbn; }, getIsbn: function(){ return ; }, setTitle: function(title){ e = title; }, getTitle: function(){ return e; }, setAuthor: function(author){ or = author; }, getAuthor: function(){ return or; } };
使用这种方法实现的.封装,虽然实现了取值器与赋值器以保护私有属性。但是在实际使用中,私有属性依然可以从外部访问,所以从根本上讲,没有实现封装。
2. 用命名规范进行区别
var Book = function(isbn,title,author){ sbn(isbn); itle(title); uthor(author); }; otype = { setIsbn: function(isbn){ this._isbn = isbn; }, getIsbn: function(){ return this._isbn; }, setTitle: function(title){ this._title = title; }, getTitle: function(){ return this._title; }, setAuthor: function(author){ this._author = author; }, getAuthor: function(){ return this._author; } };
使用这种方法与第一种类似,区别在于使用不同的命名来保护私有属性的使用。但是,从实际应用来说其仍然没有实现封装。
3. 使用函数作用域
var Book = function(newIsbn,newTitle,newAuthor){ var isbn,title,author; sbn=function(newIsbn){ isbn = newIsbn; }; sbn=function(){ return isbn; }; itle=function(newTitle){ title = newTitle; }; itle=function(){ return title; }; sbn=function(newAuthor){ author = newAuthor; }; sbn=function(){ return author; }; }
由于在JavaScript的函数中声明的变量是有作用域的,所以使用这种方法可以避免在外部直接访问私有属性。基本达到封装所要求的内容。
这里要注意的是,我们在函数的内部,可以使用以及var来声明变量。区别是使用声明的变量在外部是可以访问的。使用var声明的变量,由于受到函数作用域的保护,在函数的外部是无法直接访问的。
4. 使用函数作用域的变形
var Book = (function(){ // ...其他静态方法 return function(newIsbn,newTitle,newAuthor){ var isbn,title,author; sbn=function(newIsbn){ isbn = newIsbn; }; sbn=function(){ return isbn; }; itle=function(newTitle){ title = newTitle; }; itle=function(){ return title; }; sbn=function(newAuthor){ author = newAuthor; }; sbn=function(){ return author; }; }; })();
这种方法是直接返回一个构造器的执行。且这里的构造器是一个内嵌函数。
这种方法的优点是“在内存中只会存在一份。因为其他静态方法被声明在构造器之外,所以它们不是特权方法。”
判断一个方法是否应该被设计为静态方法的原则是“这个方法是否会访问私有属性”。如果它不需要,那么将其设计为静态方法会更有效率,因为它只会被创建一份。
常量
我们可以使用“只有取值器,没有赋值器”的方式来实现常量。
// 1. var Book = function(){ var constants = ["key1": "1","key2": "2","key3": "3"]; onstant = function(key){ return constants[key]; }; }; onstant("key1"); // 2. var Book = (function(){ var constants = ["key1": "1","key2": "2","key3": "3"]; var con = function(){}; onstant = function(name){ return constants[name]; }; return con; })(); onstant("key1");
1、利处
封装保护了内部数据的完整性;
封装使对象的重构更轻松;
弱化模块间的耦合,提高对象的可重用性;
有助于避免命名空间冲突;
……
2、弊处
私用方法很难测试;
必须与复杂的作用域链打交道,使错误调度更困难;
容易形成过度封装;
JavaScript并不原生支持封装,所以在JavaScript中实现封装存在复杂性的问题;
-
ASP.NET新型的投票结果显示方法
一个投票功能模块少不了查看投票结果,用进度条显示各个投票结果可以起到一目了然的效果。以下是我的方法,请大家不吝赐教:1:做一张图片用于做进度条,只需要很小的一个图片就可以了,如高20px,宽1px。2:在要显示进度条的单元格中插入image控件,其imageUrl设置为已做好的...
-
JavaScript数据类型学习
ECMAscript中有5种简单的数据类型,也被称为基本数据类型:Undefined、Null、Boolean、Number和String。还有一种复杂的数据类型——Object。Undefined类型在使用var声明变量但未对其进行初始化时,这个变量的值就是undefined。如:varnumber;e(number);//undefined如...
-
如何获取PHP数组的键与值呢
array_keys($array);//获取数组(字典)的所有键值,返回一个键值数组。array_values($array)://获取数组的所有value值,饭回一个数组。<?php$json='{"a":1,"b":2,"c":3,"d":4,"e":5}';//注明:value不带双引号时,其值只能是数字。【!!!注意:大括号两边只能是单引号,...
-
javascript中setInterval的用法总结
javascript中的setInterval的函数主要是在制作动画或其他间隔性渲染(操作)效果时,对操作方法按照一定时间间隔进行调用的函数。setInterval的表达式格式主要有:setInterval(fnname,time,par1,par2,);setInterval(obj,fnname,time,par1,par2,);第一种是最常见的表达...