JavaScript 面向对象编程:类与对象的创建及封装实现

作者:函数茶馆时间:2026-10-24 13:35:58浏览:644

本文深入解析 JavaScript 中类和对象的创建方法,涵盖直接赋值、JSON 格式及构造函数三种模式。重点探讨如何利用闭包实现私有变量与封装,对比传统面向对象语言特性,帮助开发者掌握 JS 中模拟继承、多态与封装的核心技巧。

JavaScript 面向对象特性概述

尽管 JavaScript 原生语法未直接提供继承、多态和封装这三大面向对象特征,但借助 prototype 等机制,我们依然能够实现这些特性,因此称其为面向对象语言并不为过。


JavaScript 对象的三种创建方式

在 JavaScript 中,构造对象主要有三种方式。


首先需明确,JavaScript 属于弱类型语言,其变量和返回值均无严格类型约束。此外,JavaScript 允许为对象动态添加任意属性和方法。基于此特性,我们可以编写如下代码:


代码如下:

 
<script type="text/javascript">
var person = {};
person.name = "飞林沙";
person.age = 21;
person.Introduce = function () {
alert("My name is " + this.name + ".I'm " + this.age);
}; 
person.Introduce();
</script>

上述代码中的 person 即为我们构建的一个对象实例。


其次,我们可以利用 JSON 格式来构造对象。


代码如下:

 
<script type="text/javascript">
var person = {
name: "飞林沙",
age: 21,
Introduce: function () { alert("My name is " + this.name + ".I'm " + this.age); }
}; 
person.Introduce();
</script>

这种写法是否让你联想到 C# 3.0 中提出的匿名对象?


代码如下:

 
protected void Page_Load(object sender, EventArgs e)
{ 
var person = new
{ 
name = "飞林沙",
age = 21
}; 
Response.Write("My name is " + person.name + ".I'm " + person.age);
} 

两者的主要区别在于,JavaScript 中函数作为一种类型可以赋值给变量,而 C# 中则不允许。


从对象到类的抽象

然而,上述两种方法仅定义了单个对象。接下来,我们将这些逻辑抽象为一个类。


代码如下:

 
<script type="text/javascript">
var Person = function () {
this.name = "飞林沙";
this.age = 21;
this.Introduce = function () {
alert("My name is " + this.name + ".I'm " + this.age);
}; 
}; 
var person = new Person();
person.Introduce();
</script>

在此示例中,属性值已被硬编码,无法为每个对象定制。解决此问题的方法很简单:


代码如下:

 
<script type="text/javascript">
var Person = function (name, age) {
this.name = name;
this.age = age;
this.Introduce = function () {
alert("My name is " + this.name + ".I'm " + this.age);
}; 
}; 
var person = new Person("飞林沙", 21);
person.Introduce();
</script>

对象属性访问与封装实现

对比第二种和第三种写法,两者在功能上是等效的。第二种写法构建的是一个 JSON 对象,而 JSON 本质上是键值对的集合。我们可以据此理解对象的结构。


让我们通过以下测试代码进行验证:


代码如下:

 
<script type="text/javascript">
var Person = function (name, age) {
this.name = name;
this.age = age;
this.Introduce = function () {
alert("My name is " + name + ".I'm " + age);
}; 
}; 
var person = new Person("飞林沙", 21);
for (var p in person) {
alert(p);
} 
alert(person["name"]);
</script>

上述代码运行无误:首先通过遍历获取 person 的所有键(属性和方法名),随后通过索引方式访问 name 属性。


这里引出一个问题:从传统面向对象语言的角度看,name 和 age 应属于私有变量。直接通过 person 访问是否破坏了封装性?


回顾前文提到的概念:使用 var 声明的是局部变量,而未使用 var 的则是对象属性。若将代码修改如下:


代码如下:

 
<script type="text/javascript">
var Person = function (name, age) {
var name = name;
var age = age;
this.GetName = function () {
return name;
} 
this.GetAge = function () {
return age;
} 
this.Introduce = function () {
alert("My name is " + name + ".I'm " + age);
}; 
}; 
var person = new Person("飞é林?沙3", 21);
alert(person["name"]);
alert(person.GetName());
</script>

这样即可实现良好的封装,这也是 JavaScript 中实现封装的一种典型方式。


关于 JavaScript 类和对象的讨论暂告一段落,但其中仍存在一些问题,将在后续文章中详细探讨。

作者最新文章