首页 > 网站 > WEB开发 > 正文

javascript实现私有变量、方法

2024-04-27 15:03:22
字体:
来源:转载
供稿:网友

js中创建对象的基本模式有3种,完全暴露型(fully exposed)只能提供公用成员,第二种方法使用下划线来表示方法或者属性的私用性。第三种方法使用闭包来创建真正私用的成员,这些成员只能通过一些特权方法访问

完全暴露

var Book = function(isbn, title, author){ isbn == undefined ? throw new Error('Book constructor requires an isbn'); this.isbn = isbn; this.title = title || 'No title specified'; this.author = author || 'No author specified'; } Book.PRototype.display = function(){ ... }

这里的isbn如果在构造函数中没有定义,就会抛出错误,但我们也许需要对这些数据有更多的验证,那么就来到以下这种

var Book = function(isbn, title, author){ this.setIsbn(isbn); this.setTitle(title); this.setAuthor(author); } Book.prototype = { checkIsbn: function(isbn){ }, setIsbn: function(isbn){ if(!this.checkIsbn) throw new Error('..'); this.isbn = isbn; }, setTitle: function(title){ this.title = title || 'No title specified'; }, getTitle: function(){ return this.title; }, ... }

尽管这样的set、get方法的设置很像一些面向对象语言如java,但没有使用private关键字导致了title、author这些属性还是公开的,这样对内部数据就无法进行保护,其他一起协作的人可能无意改动了这些属性

用命名规范区别私用成员

下划线是一种命名规范,它表明一个属性(或方法)仅供对象内部使用,直接访问它或者设置它可能导致意想不到的后果

var Book = function(isbn, title, author){ this.setIsbn(isbn); this.setTitle(title); this.setAuthor(author); } Book.prototype = { _checkIsbn: function(isbn){ }, setIsbn: function(isbn){ if(!this.checkIsbn) throw new Error('..'); this._isbn = isbn; }, setTitle: function(title){ this._title = title || 'No title specified'; }, getTitle: function(){ return this._title; }, ... }

使用闭包真正实现私有

在js中,只有函数具有作用域,在一些强类型语言如java中的{}就能创建块级作用域,这在js中并不存在。那么私有属性本质而言就是你希望对象外部无法访问的变量,所以实现这种需求而求助于作用域概念是合情合理的

var Book = function(newIsbn, newTitle, newAuthor){ //private attributes var isbn, title, author; //private method function checkIsbn(isbn){ ... } //privileged methods this.getTitle = function(){ //返回变量title,而不是this.title return title; } this.setTitle = function(newTitle){ title = newTitle || 'No title specified' } //Constructor code this.setTitle(newTitle); } //Public, non-privileged methods Book.prototype = { display: function(){ ... } }

原本我们用对象的属性,而现在使用var而不是this声明这些变量,这意味着它们只存在于Book构造器中。那么我们使用get方法取这些变量的时候,形成了闭包。 需要访问这些私有变量的方法声明在Book中即可,这些方法称为特权方法,任何不需要直接访问私有属性的方法都可以像原来那样在Book.prototype中声明。用这种对象创建方式真正实现了私有变量,但有一些缺点。完全暴露型所有方法都在原型对象中,不管new了多次,生成多少对象实例,对于方法的记录内存中只需要一份,所以这里的闭包方法性能不好。其次,这个方法也不适用于派生子类,因为js的原型继承围绕原型,可以参考我的另一篇文章原型继承和应用,一旦实现继承,子类对象根本拿不到父类中的私有变量,导致了“继承破坏封装”


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表