欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javascript中如何创建对象

程序员文章站 2022-03-27 12:20:28
...
在js中,对象是对象,函数也是对象,对于java程序员来说,这非常容易造成困惑。 而且究竟什么是类呢? js好像也没有一个明确的规范。我目前的理解是,把prototype当作类型接口,但实际上对于js来说,创建一个对象,并不一定需要创建一个新的类型。

这就造成了在js中创建对象的奇怪行为, 最简单的构造方式:

var oObj = new Object();
oObj.attr_1 = "string value";
oObj.attr_2 = 4;
oObj.attr_3 = function() {alert("");}


可是这样便会产生一个问题,对于同一种类型,只能产生一个对象。在面向对象的程序设计里面,这是件搞笑的事情。我们必须想出办法来,可以同时为一个定义的类型产生多个对象:

function createObj() {
var oObj = new Object();
oObj.attr_1 = "string value";
oObj.attr_2 = 4;
oObj.attr_3 = function() {alert(this.attr_1);}

return oObj;
}

var oObj1 = createObj();
var oObj2 = createObj();


看起来很怪异,可这就是js中所谓的“构造函数”。 通过这种方式,我们可以产生多个具有相同的属性和方法的对象。

在这里,这个函数就被当作全局函数来使用,而不是对象。 在做js编程时,我们必须始终在心里有数,我创建的每个函数或者方法,我是打算把它当作什么来用的,是函数还是对象? 这样就不会糊涂了。

上面的代码看上去很美,其实问题多多。 首先是每个属性值都是固定的,对于不同的对象,我们应该可以赋予不同的属性,所以我们把构造函数改一改:

function createObj(sAttr1, nAttr2) {
var oObj = new Object();
oObj.attr_1 = sAttr1;
oObj.attr_2 = nAttr2;
oObj.attr_3 = function() {alert(this.attr_1);}

return oObj;
}

var oObj1 = createObj("string1", 4);
var oObj2 = createObj("string2", 5);


还有一个问题就是,每当我call一次createObj的时候,一个新的方法attr_3就会被创建。 而我们知道,在传统的面向对象设计中,方法是可以重用的。所有的对象都不产生创建自己的方法,而是指向方法堆里面的类记录。

那么在js中,我们该怎么模拟这种情况呢? 看看下面的代码:

function fAttr() {alert(this.attr_1);

function createObj(sAttr1, nAttr2) {
var oObj = new Object();
oObj.attr_1 = sAttr1;
oObj.attr_2 = nAttr2;
oObj.attr_3 = fAttr;

return oObj;
}

var oObj1 = createObj("string1", 4);
var oObj2 = createObj("string2", 5);


这样就对了,属性仅仅是指向一个预先创建好的函数,不会每次都重新创建了。

然而这样看上去还是显得有点奇怪,首先,函数fAttr似乎并不和构造函数融为一体,作为传统面向对象程序员,这样的代码,看着很不爽。

这个时候prototype就派上用场了:

function createObj() {

}

createObj.prototype.attr_1 = 4;
createObj.prototype.attr_2 = "string1";
createObj.prototype.attr_3 = function() {alert(this.attr_1);

var oObj1 = new createObj();
var oObj2 = new createObj();


这段代码保证了所有数据都是在原型中有一份的,那么每个新创建的对象,自然也有一份。在这里,我们要记住,createObj()应该被视为对象,而不是函数.

根据java coding style把代码改规范一点:

function Obj() {

}

Obj.prototype.attr_1 = 4;
Obj.prototype.attr_2 = "string1";
Obj.prototype.attr_3 = function() {alert(this.attr_1);

var oObj1 = new Obj();
var oObj2 = new Obj();

怎么样,像那么回事了吧。但是问题又来了,我们又回到老路上去了,每个对象的属性值又变成固定的了。

我们把刚才使用的两种方式结合起来:

function Obj(a1,a2) {
this.attr_1 = a1;
this.attr_2 = a2;
}

Obj.prototype.attr_3 = function() {alert(this.attr_1);

var oObj1 = new Obj(5, "String1");
var oObj2 = new Obj(6, "String2");


这样把属性和方法分开定义,更加有面向对象的感觉。

但是,极端的完美主义者还是觉得不满意,认为这样的类型定义,没有java中的类定义那么清晰,完美封装。 于是,专为java变态狂设计的方法诞生了:


function Obj(a1,a2) {
this.attr_1 = a1;
this.attr_2 = a2;

if(typeof Obj._inited == "undefined") {
Obj.prototype.attr_3 = function() {alert(this.attr_1);

Obj._inited = true;
}
}

var oObj1 = new Obj(5, "String1");
var oObj2 = new Obj(6, "String2");


特此鸣谢javascript高级程序设计