JavaScript 特权方法模式:实现真正的私有属性

作者:代码拾荒

时间:2026-10-26

浏览:454

本文详解 JavaScript 中的特权方法模式,通过闭包机制确保对象属性的真正私有化。文章对比了不使用 new 的关键字调用与构造函数调用两种方式,指出后者会导致属性公开。通过实例展示如何利用 that 载体和共享变量实现属性的安全读写与继承扩展。

文章目录

特权方法模式与私有属性封装

该模式的核心价值在于实现对象属性的严格私有化。外部代码无法直接访问或修改对象的内部状态,所有的交互必须通过预先定义的特权方法进行。


为了更直观地理解,下面提供一个具体的代码示例。


具体实现代码如下:

 
var person = function(cfg) {
var that = {};
that.getName = function() {
return cfg.name || 'unknow name';
}; 
// 性别 默认男性
that.getGender = function() {
return cfg.gender || 'male';
}; 
return that;
}; 
var programmer = function(cfg) {
var that = person(cfg),
share = {};
share.status = 'normal';
that.getFamiliarLanguage = function() {
return (cfg.langs || []).join(' ');
}; 
that.getProfile = function() {
return 'hi,my name is ' + that.getName();
}; 
that.getStatus = function() {
return share.status;
}; 
that.setStatus = function(status) {
share.status = status;
}; 
return that;
}; 
var me = programmer({
name: 'AndyZhang',
gender: 'male',
// 熟悉的语言
langs: ['javascript', 'java', 'php']
}); 
console.debug(me.getFamiliarLanguage());
console.debug(me.getProfile());
me.setStatus('oh really busy..');
console.debug(me.getStatus());

构造函数调用与私有化的冲突

观察上述代码可以发现,调用 programmer 函数时并未使用 new 关键字,且函数内部也未出现 this 关键字。


如果代码中类似 this.name = cfg.name 这样的属性赋值存在,并采用 new 关键字进行构造函数调用,生成的对象属性将变为公开状态,不再具备私有特性。例如:


代码如下:

 
// 这里方法名的首字母大写 以表示作为一个构造方法 用new来调用
var Person = function(cfg) {
this.name = cfg.name;
this.gender = cfg.gender;
} 
// new出一个person1
var person1 = new Person({
name: 'Andrew',
gender: 'male'
}); 
// 本来是想让name, gender成为私有 用类似setter getter方法来读写 就像javaBean一样
alert(person1.name); // 'Andrew'
alert(person1.gender); // 'male'

私有属性约定的替代方案

从上述示例可以看出,person1 对象的属性可以直接被外部访问,未能实现真正的私有保护。在实际开发中,有时会通过代码规范或约定来标识私有属性,例如使用 this._name 表示 name 为私有属性。只要团队统一约定,这也是一种可行的方式,在诸如 YUI2 等第三方 JS 库中较为常见。


基于闭包的继承与状态共享

回到最初的代码,由于未使用 this,而是采用 that 作为对象载体。在 programmer 方法中,that 起到了关键作用:调用 person 后返回的 that 已具备 person 的所有方法(如 getName、getGender)。随后,根据 programmer 的具体需求在 that 基础上进行扩展,甚至覆盖原有方法。此外,programmer 中的 share 变量可用于集中管理私有变量和方法。借助 JavaScript 的作用域(scope)和闭包(closure)机制,that 扩展的方法可以访问和处理这些共享数据,例如代码中的 that.getStatus 和 that.setStatus 方法。最后通过 return that 返回对象实例。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章