JavaScript面向对象编程实战:从类定义到this指针处理

作者:拾光时间:2026-10-28 17:24:05浏览:124

本文深入解析如何在JavaScript中实现面向对象编程。通过function关键字定义类,利用var和this区分私有与公有属性及方法。文章详细演示了如何模拟构造函数、处理带参构造,并重点解决了事件回调中this指针指向错误的问题,提供实用的代码实现方案。

对象泛指人们研究的任何事物,无论是简单的整数还是复杂的飞机,甚至抽象的规则、计划或事件均可视为对象。

面向对象编程是目前主流的编程范式,但令人遗憾的是,前端开发中最常用的JavaScript语言原生并不直接支持这一特性。

JavaScript缺乏访问控制符、class关键字、继承关键字extend或冒号,以及虚函数virtual,但这门灵活的语言允许我们通过其他方式实现类的定义与对象创建。

定义类并创建实例

接下来我们将探讨如何定义类并创建类的实例对象。

在JavaScript中,我们可以使用function关键字来定义类,具体示例如下。

代码如下:

function Shape()
{
var x=1;
var y=2;
} 

这看起来像是在定义函数,确实如此,我们定义了一个名为Shape的函数并初始化了x和y。但从另一个角度看,这等同于定义了一个包含x和y两个属性(初始值分别为1和2)的Shape类,只是定义类的关键字换成了function而非class。

随后,我们可以创建Shape类的实例对象aShape,代码如下。

代码如下:

var aShape = new Shape();

公有与私有属性定义

下面介绍如何定义类的公有属性和私有属性。

虽然我们创建了aShape对象,但直接访问其属性时会报错,例如尝试执行aShape.x=1;时会出现错误。

代码如下:

aShape.x=1;

这表明使用var定义的属性是私有的。若要定义公有属性,必须使用this关键字。

代码如下:

function Shape()
{
this.x=1;
this.y=2;
}  

这样即可访问Shape的属性,例如执行aShape.x=2;。

代码如下:

aShape.x=2;

总结上述代码可知:使用var可定义类的私有属性,而使用this可定义类的公有属性。

公有与私有方法定义

接下来讨论公有方法和私有方法的定义。

在JavaScript中,函数是Function类的实例,间接继承自Object,因此函数也是对象。我们可以通过赋值方式创建函数,或将函数赋给类的属性变量,从而使其成为可执行的方法。

代码如下:

function Shape()
{
var x=0;
var y=1;
this.draw=function()
    {
//print;
    };
}  

我们在上述代码中定义了draw方法,并将一个function赋值给它。随后,我们可以通过aShape调用该函数,这在面向对象编程中称为公有方法,例如执行aShape.draw();。

代码如下:

aShape.draw();

若使用var定义draw,则该函数变为私有方法,例如尝试通过aShape.draw调用时会失败。

代码如下:

function Shape()
{
var x=0;
var y=1;
var draw=function()
    {
//print;
    };
}  

此时无法通过aShape.draw调用该函数。

构造函数与带参构造

关于构造函数的实现。

JavaScript原生不支持面向对象,因此也没有构造函数,但我们可以模拟一个在对象创建时自动调用的构造函数,代码如下。

代码如下:

function Shape()
{
var init = function()
    {
//构造函数代码
    };
init();
}  

在Shape函数末尾手动调用init函数,这样每次创建Shape对象时init都会自动执行,从而模拟构造函数。

关于带参数的构造函数。

实现带参构造函数很简单,只需将传入参数写入函数参数列表即可,例如。

代码如下:

function Shape(ax,ay)
{
var x=0;
var y=0;
var init = function()
    {
//构造函数
x=ax;
y=ay;
    };
init();
}  

这样我们就可以通过以下方式创建对象。

代码如下:

var aShape = new Shape(0,1);

静态属性与方法

关于静态属性和静态方法的定义。

在JavaScript中定义静态属性和方法的方法如下所示。

代码如下:

function Shape(ax,ay)
{
var x=0;
var y=0;
var init = function()
    {
//构造函数
x=ax;
y=ay;
    };
init();
}
Shape.count=0;//定义一个静态属性count,这个属性是属于类的,不是属于对象的。
Shape.staticMethod=function(){};//定义一个静态的方法

有了静态属性和方法,就可以通过类名访问它们,例如。

代码如下:

alert ( aShape.count );
aShape.staticMethod();

注意:静态属性和方法目前均为公有,尚不清楚如何将其设为私有。

方法内属性访问与this指针处理

在方法中访问本类的公有属性和私有属性。

在类的方法中访问自身属性时,JavaScript对公有和私有属性的访问方式不同,请看以下代码。

代码如下:

function Shape(ax,ay)
{
var x=0;
var y=0;
this.gx=0;
this.gy=0;
var init = function()
    {
x=ax;//访问私有属性,直接写变量名即可
y=ay;
this.gx=ax;//访问公有属性,需要在变量名前加上this.
this.gy=ay;
    };
init();
}  

关于this的注意事项。

根据经验,类中的this并不始终指向当前对象,主要原因是JavaScript非原生面向对象语言,且函数和类均使用function定义,这可能导致一些问题。

this指针出错通常发生在事件处理中。当希望某个对象的成员函数响应事件时,系统调用该成员函数,但传入的this指针已不再是原对象,此时在成员函数中调用this会出错。

解决方法是在定义类时将this保存到一个私有属性中,后续用该属性替代this。这种方法使用this指针较为安全且省心。

我们修改代码以解决this问题,对照第六部分的代码即可理解。

代码如下:

function Shape(ax,ay)
{
var _this=this; //把this保存下来,以后用_this代替this,这样就不会被this弄晕了
var x=0;
var y=0;
_this.gx=0;
_this.gy=0;
var init = function()
    {
x=ax;//访问私有属性,直接写变量名即可
y=ay;
_this.gx=ax;//访问公有属性,需要在变量名前加上this.
_this.gy=ay;
    };
init();
} 

以上讨论了如何在JavaScript中定义类、创建对象、定义公有和私有属性及方法、创建静态属性和方法、模拟构造函数,并探讨了易错的this指针。

关于JavaScript中面向对象实现的讨论至此结束,上述内容最为实用,通常足以满足JavaScript定义类和创建对象的需求。当然,也可以使用mootools或prototype等框架,它们对类模拟更完善,支持继承。若使用框架需引入相关js文件,但掌握无框架下的类创建能提高效率,且可见创建简单类并不复杂。

作者最新文章