JavaScript 面向对象封装:私有属性与特权方法详解
本文通过手机类示例,详解JavaScript中利用闭包实现私有属性count的方法。讲解如何在构造函数中初始化实例,将公有方法挂载至原型对象以节省内存,并定义特权方法访问私有变量。最后通过测试代码验证索引计数与构造函数指向的正确性,展示完整的封装流程。
JavaScript 面向对象封装:私有属性与特权方法详解
首先通过一个具体示例来演示封装过程。
定义手机类与私有属性
第一步:定义一个表示“手机”的类。
具体实现代码如下:
var MobilePhone = (function(){
…………
})() 第二步:分析该类所需的私有属性。在此示例中,我们需要统计实例化出的手机数量。
相关代码如下:
var MobilePhone = (function(){
//私有属性
var count = 0; //代表手机的数量
})() 构造函数与原型方法
第三步:创建构造函数,用于实例化新对象时的初始化操作,包括属性和方法的初始化。在本例中,每部手机都具备颜色、尺寸和价格属性。由于构造函数是闭包的一部分,它可以访问私有变量 count,且只要存在引用,count 的值就会长期保存在内存中。
代码实现如下:
var MobilePhone = (function(){
//私有属性
var count = 0; //代表手机的数量
//构造函数
var creatphone = function(color,size,price){
count++;
this._color = color; //手机的颜色
this._size = size; //手机的大小
this._price = price; //手机的价格
this.index = count; //手机索引,是第几台创建的手机手象
}
})() 第四步:定义共有方法。
共有方法是所有实例化后的手机对象均可使用的方法。例如,手机应具备修改价格、颜色和尺寸的功能,以及显示这些属性的功能。
共有方法应放置在“原型对象”中,原因如下:
1. 所有通过该构造函数实例化的对象(即生成的手机)都能使用原型对象中的方法。
2. 若将方法放在构造函数内部,每次实例化手机对象时都会生成重复的方法副本,从而浪费内存。
3. 关于 "constructor":creatphone 的解释:
执行 creatphone.prototype = {……} 会覆盖原有的原型对象引用。为了使原型对象与该构造函数重新关联,需设置 "constructor":creatphone 属性。
具体代码如下:
var MobilePhone = (function(){
//私有属性
var count = 0;//代表手机的数量
//构造函数
var creatphone = function(color,size,price){
count++;
this._color = color; //手机的颜色
this._size = size; //手机的大小
this._price = price; //手机的价格
this.index = count; //手机索引,是第几台创建的手机手象
}
//公有方法,存放在原型对象中
creatphone.prototype = {
"constructor":creatphone,
//获取手机颜色
"getColor" : function(){
return this._color;
},
//设置手机颜色
"setColor" : function(color){
this._color = color;
},
//获取手机大小
"getSize" : function(){
return "width:"+this._size.width + " height:" + this._size.height;
},
//设置手机大小
"setSize" : function(size){
this._size.width = size.width;
this._size.height = size.height;
},
//获取手机价格
"getPrice" : function(){
return this._price;
},
//设置手机价格
"setPrice" : function(price){
this._price = price
}
}
})() 特权方法与测试验证
第五步:定义特权方法,即能够访问类私有变量的方法。在此例中,我们需要一个方法来获取已创建的手机对象总数。
代码实现如下:
var MobilePhone = (function(){
//私有属性
var count = 0;//代表手机的数量
var index = 0;//代表手机的索引
//构造函数
var creatphone = function(color,size,price){
count++;
this._color = color; //手机的颜色
this._size = size; //手机的大小
this._price = price; //手机的价格
this.index = count; //手机索引,是第几台创建的手机手象
} //公有方法,存放在原型对象中
creatphone.prototype = {
"constructor":creatphone,
"getColor" : function(){
return this._color;
},
"setColor" : function(color){
this._color = color;
},
"getSize" : function(){
return "width:"+this._size.width + " height:" + this._size.height;
},
"setSize" : function(size){
this._size.width = size.width;
this._size.height = size.height;
},
"getPrice" : function(){
return this._price;
},
"setPrice" : function(price){
this._price = price
}
}
//特权方法
creatphone.get_count_index = function(){
return count
}
return creatphone;
})() 使用上述封装的手机类进行测试。
测试代码如下:
var anycall = new MobilePhone(); //实例一个三星手机对象
var HTC = new MobilePhone(); //实例一个HTC手机对象
var Iphone4s = new MobilePhone(); //实例一个苹果4S手机对象
console.log("三星是第:"+anycall.index+"台"); //FF的控制台输出三星手机对象是第几台创建的,即索引;
console.log("HTC是第:"+HTC.index+"台"); //FF的控制台输出HTC手机对象是第几台创建的,即索引;
console.log("Iphone4s是第:"+Iphone4s.index+"台"); //FF的控制台输出个苹果4S手机对象是第几台创建的,即索引;
console.log("总共造出了"+MobilePhone.get_count_index()+"手机"); //FF的控制台输出总共创建了几台手机;
console.log(anycall.constructor === MobilePhone); //实例出来的对象,的原形象中的constructor,是否还指向MobilePhone 运行结果如下,完全正确:

什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
