javascript中如何创建对象
程序员文章站
2022-03-27 12:20:28
...
在js中,对象是对象,函数也是对象,对于java程序员来说,这非常容易造成困惑。 而且究竟什么是类呢? js好像也没有一个明确的规范。我目前的理解是,把prototype当作类型接口,但实际上对于js来说,创建一个对象,并不一定需要创建一个新的类型。
这就造成了在js中创建对象的奇怪行为, 最简单的构造方式:
可是这样便会产生一个问题,对于同一种类型,只能产生一个对象。在面向对象的程序设计里面,这是件搞笑的事情。我们必须想出办法来,可以同时为一个定义的类型产生多个对象:
看起来很怪异,可这就是js中所谓的“构造函数”。 通过这种方式,我们可以产生多个具有相同的属性和方法的对象。
在这里,这个函数就被当作全局函数来使用,而不是对象。 在做js编程时,我们必须始终在心里有数,我创建的每个函数或者方法,我是打算把它当作什么来用的,是函数还是对象? 这样就不会糊涂了。
上面的代码看上去很美,其实问题多多。 首先是每个属性值都是固定的,对于不同的对象,我们应该可以赋予不同的属性,所以我们把构造函数改一改:
还有一个问题就是,每当我call一次createObj的时候,一个新的方法attr_3就会被创建。 而我们知道,在传统的面向对象设计中,方法是可以重用的。所有的对象都不产生创建自己的方法,而是指向方法堆里面的类记录。
那么在js中,我们该怎么模拟这种情况呢? 看看下面的代码:
这样就对了,属性仅仅是指向一个预先创建好的函数,不会每次都重新创建了。
然而这样看上去还是显得有点奇怪,首先,函数fAttr似乎并不和构造函数融为一体,作为传统面向对象程序员,这样的代码,看着很不爽。
这个时候prototype就派上用场了:
这段代码保证了所有数据都是在原型中有一份的,那么每个新创建的对象,自然也有一份。在这里,我们要记住,createObj()应该被视为对象,而不是函数.
根据java coding style把代码改规范一点:
怎么样,像那么回事了吧。但是问题又来了,我们又回到老路上去了,每个对象的属性值又变成固定的了。
我们把刚才使用的两种方式结合起来:
这样把属性和方法分开定义,更加有面向对象的感觉。
但是,极端的完美主义者还是觉得不满意,认为这样的类型定义,没有java中的类定义那么清晰,完美封装。 于是,专为java变态狂设计的方法诞生了:
特此鸣谢javascript高级程序设计
这就造成了在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高级程序设计
上一篇: dp和sp的区别 以及字体
下一篇: PHP实现微信支付功能开发代码分享