本文详细解析JavaScript中对象的创建与操作机制。内容涵盖动态属性与方法添加、点符号与方括号访问的区别、对象字面量语法及JSON转换。重点讲解函数作为对象、利用构造函数与prototype属性实现类似类的实例共享,以及通过闭包创建私有成员和定义命名空间以避免冲突的最佳实践。
JavaScript对象基础与动态属性
JavaScript语言中并未提供传统的类定义机制,因此在创建对象时不存在固定的模板约束。开发者可以动态地为对象添加新的属性和方法。在动态创建新属性时,核心操作即为该属性赋予相应的值。以下示例演示了如何创建一个对象并为其增加x和y两个属性。
代码如下:
var Programmer = new Object();
Programmer.name = "Young";
Programmer.age = 25;
alert(Programmer.name + " : " + Programmer.age); JavaScript对象的概念与C#或VB中的对象有显著差异。在JavaScript中,对象可被视为一组键值对的集合,通常通过“对象.属性名”的方式访问属性。这种结构类似于.NET Framework中的Dictionary类,开发者也可以使用方括号操作符“[]”来创建或访问对象属性。
代码如下:
var Programmer = new Object();
Programmer["name"] = "Young";
Programmer["age"]= 25;
document.getElementById("message").innerHTML=Programmer["name"] + " : " + Programmer["age"];
alert(Programmer.name + " : " + Programmer.age); 通过上述示例可以看出,这两种访问对象属性的方式在功能上是等效的。需要注意的是,如果尝试访问一个尚未创建的属性,系统将返回“undefined”。 同样地,我们可以将函数作为键值对集合中的值进行添加,从而构建对象的方法。
代码如下:
var Programmer = new Object();
Programmer["name"] = "Young";
Programmer.age= 25;
Programmer.speak=function(){
alert(this.name + " : " + this["age"]);
}
Programmer.speak(); 在上述代码中,我们交替使用了点号“.”和方括号“[]”来定义和访问属性及方法。这两种操作符在功能上是一致的,但混用有时会导致概念上的混淆,特别是在为已存在的属性设置新值时,表达意图可能不够清晰。接下来我们将介绍第三种语法,以更明确地表达对象初始化的意图。
代码如下:
var Programmer =
{
name : "Young",
age : 25,
speak : function(){ alert(this.name + " : " + this.age); }
}
Programmer.speak(); 上述代码更清晰地展示了对象初始化的开始与结束。此外,我们还可以利用这种语法在对象中嵌套其他对象。例如:var Programmer =
{
Figure : {name : "Young" , age : 25 },
Company : {name : " Arcadia" , address : "ShenZheng"},
speak : function(){
alert("name:"+this.Figure.name+"\nage:"+this.Figure.age + "\nCompany:"+this.Company.name+" of
"+this.Company.address);
}
};
Programmer.speak(); 对象字面量与JSON数据交换
这种语法因其意图明确且代码紧凑而广受欢迎,常见于各种流行的JavaScript框架中。目前互联网上广泛使用的JavaScript Object Notation(JSON)也采用了类似的语法。JSON是一种轻量级的数据交换格式,易于机器解析和生成,且语法严格。它允许JavaScript在互联网上高效交换数据,我们可以使用eval函数将JSON字符串转换为本地JavaScript对象。
代码如下:
var Programmer="({name: 'Young',age : 25})";
var p = eval(Programmer);
alert(p.name + ',' + p.age); 函数作为对象与原型链应用
通过上述讨论,我们明确了JavaScript对象本质上是一组字典。在JavaScript中,另一个重要的概念是函数。
1:在JavaScript中,函数本身就是一个对象,这一点与C#中的方法概念完全不同。请看以下示例。
代码如下:
function add(point1, point2)
{
var result = {
x : point1.x + point2.x,
y : point1.y + point2.y
}
return result;
}
var p1 = { x: 1, y: 1 };
var p2 = { x: 2, y: 2 };
var p3 = add(p1, p2);
alert(p3.x + "," + p3.y);2:将函数作为对象的方法。 var Boy=
{
name:"Young",
Love:function(Girl){
return this.name+" 爱上了 "+Girl.name
}
}
var Girl={
name:"Jing"
}
alert(Boy.Love(Girl)); 现在面临的问题是,两个相似的对象中,一个拥有love方法,而另一个没有。由于我们没有定义类似C#的类,只是简单创建了两个对象,如果期望这两个对象都具备love方法,可以按如下方式定义。
代码如下:
function LoveRelation(person){
alert(this.name+" 爱上了 "+person.name);
}
var person1={
name:"Young",
Love:LoveRelation
}
var person2={
name:"Jing",
Love:LoveRelation
}
person1.Love(person2); 上述代码看似在创建一个person类,并创建两个实例以赋予它们相同的特征。然而,显然上述代码并不完善。我们可以通过两种途径来满足这一要求。
途径1:
代码如下:
function Person(n)
{
this.name=n;
this.Love=function(person)
{
alert(this.name+" 爱上了 "+person.name);
}
}
var person1=new Person("Young");
var person2=new Person("Jing");
person1.Love(person2); 途径2:利用JavaScript对象的prototype属性。
代码如下:
function Person(n)
{
this.name=n;
}
Person.prototype.Love=function(person)
{
alert(this.name+" 爱上了 "+person.name);
}
var person1=new Person("Young");
var person2=new Person("Jing");
person1.Love(person2);
person2.Love(person1); 在上述示例中,我们可以将Person函数视为Person对象的构造器,而所有通过此构造器创建的对象都共用一个prototype属性。
私有成员与命名空间定义
在Douglas Crockford的<a href="http://www.crockford.com/javascript/private.html">Private Members In JavaScript"</a>一文中,作者详细演示了如何创建对象的私有成员。其核心思想在此不再赘述,我们仅对那个demo进行简单的重写。
代码如下:
function Point(x, y)
{
this.get_x = function() { return x; }
this.set_x = function(value) { x = value; }
this.get_y = function() { return y; }
this.set_y = function(value) { y = value; }
}
Point.prototype.print = function()
{
return this.get_x() + ',' + this.get_y();
}
var p = new Point(2,2);
p.set_x(4);
alert(p.print()); 最后,我们讲解JavaScript对象的命名空间。命名空间可以消除同名类型之间的冲突,熟悉C#的朋友对此一定非常清楚。我们可以在JavaScript中通过以下代码来定义命名空间。 var Arcadia = {}
代码如下:
Arcadia.Person=function(n)
{
this.name=n;
}
Arcadia.Person.prototype.Love=function(person)
{
alert(this.name+" 爱上了 "+person.name);
}
var person1=new Arcadia.Person("Young");
var person2=new Arcadia.Person("Jing");
person1.Love(person2);