浅谈JavaScript实现面向对象中的类


Posted in Javascript onDecember 09, 2014

对象,是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。--引自百度百科

面向对象编程,是当前最流行的编程模式。但令人沮丧的是,作为前端应用最为广泛的javascript,并不支持面向对象。

    javascript没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用 来支持虚函数的virtual,不过,Javascript是一门灵活的语言,下面我们就看看没有关键字class的Javascript如何实现类定 义,并创建对象。

定义类并创建类的实例对象

在Javascript中,我们用function来定义类,如下:

function Shape()

{

    var x=1;

    var y=2;

}

你或许会说,疑?这个不是定义函数吗?没错,这个是定义函数,我们定义了一个Shape函数,并对x和y进行了初始化。不过,如果你换个角度来 看,这个就是定义一个Shape类,里面有两个属性x和y,初始值分别是1和2,只不过,我们定义类的关键字是function而不是class。

然后,我们可以创建Shape类的对象aShape,如下:

var aShape = new Shape();

定义公有属性和私有属性

我们已经创建了aShape对象,但是,当我们试着访问它的属性时,会出错,如下:

aShape.x=1; 

这说明,用var定义的属性是私有的。我们需要使用this关键字来定义公有的属性。

function Shape()

{

    this.x=1;

    this.y=2;

} 

这样,我们就可以访问Shape的属性了,如:

aShape.x=2; 

好,我们可以根据上面的代码总结得到:用var可以定义类的private属性,而用this能定义类的public属性。

定义公有方法和私有方法

在Javascript中,函数是Function类的实例,Function间接继承自Object,所以,函数也是一个对象,因此,我们可 以用赋值的方法创建函数,当然,我们也可以将一个函数赋给类的一个属性变量,那么,这个属性变量就可以称为方法,因为它是一个可以执行的函数。代码如下:

function Shape()

{

    var x=0;

    var y=1;

    this.draw=function()

    {

        //print;

    };

} 

我们在上面的代码中定义了一个draw,并把一个function赋给它,下面,我们就可以通过aShape调用这个函数,OOP中称为公有方法,如:

aShape.draw(); 

如果用var定义,那么这个draw就变成私有的了,OOP中称为私有方法,如:

function Shape()

{

    var x=0;

    var y=1;

    var draw=function()

    {

        //print;

    };

} 

这样就不能使用aShape.draw调用这个函数了。

构造函数

Javascript并不支持OOP,当然也就没有构造函数了,不过,我们可以自己模拟一个构造函数,让对象被创建时自动调用,代码如下:

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(); 

注意:静态属性和方法都是公有的,目前为止,我不知道如何让静态属性和方法变成私有的~

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

在类的方法中访问自己的属性,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并不是OOP语言,而且,函数和类均用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中的OOP实现就聊到这里,以上是最实用的内容,一般用Javascript定义类,创建对象用以上的代码已经足够 了。当然,你还可以用mootools或prototype来定义类,创建对象。我用过mootools框架,感觉很不错,它对Javascript的类 模拟就更完善了,还支持类的继承,有兴趣的读者可以去尝试一下。当然,如果使用了框架,那么在你的网页中就需要包含相关的js头文件,因此我还是希望读者 能够在没有框架的情况下创建类,这样,代码效率较高,而且你也可以看到,要创建一个简单的类并不麻烦~

Javascript 相关文章推荐
JavaScript iframe的相互操作浅析
Oct 14 Javascript
jquery的each方法使用示例分享
Mar 25 Javascript
JavaScript中实现异步编程模式的4种方法
Sep 24 Javascript
简单实现限制uploadify上传个数
Nov 16 Javascript
jquery计算出left和top,让一个div水平垂直居中的简单实例
Jul 13 Javascript
基于JavaScript表单脚本(详解)
Oct 18 Javascript
编写React组件项目实践分析
Mar 04 Javascript
Angular父子组件通过服务传参的示例方法
Oct 31 Javascript
vuex存值与取值的实例
Nov 06 Javascript
mpvue微信小程序开发之实现一个弹幕评论
Nov 24 Javascript
详解react组件通讯方式(多种)
May 06 Javascript
夯基础之手撕javascript继承详解
Nov 09 Javascript
node.js中的console.trace方法使用说明
Dec 09 #Javascript
node.js中的console.time方法使用说明
Dec 09 #Javascript
node.js中的console.timeEnd方法使用说明
Dec 09 #Javascript
node.js中的path.basename方法使用说明
Dec 09 #Javascript
JavaScript 开发工具webstrom使用指南
Dec 09 #Javascript
node.js中的path.delimiter方法使用说明
Dec 09 #Javascript
node.js中的path.dirname方法使用说明
Dec 09 #Javascript
You might like
关于php正则匹配汉字的方法介绍
2013/04/25 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
PHP实现链表的定义与反转功能示例
2018/06/09 PHP
在IE6下发生Internet Explorer cannot open the Internet site错误
2010/06/21 Javascript
父子窗体间传递JSON格式的数据的代码
2010/12/25 Javascript
js 关于=+与+=日期函数使用说明(赋值运算符)
2011/11/15 Javascript
js添加table的行和列 具体实现方法
2013/07/22 Javascript
JQuery对表单元素的基本操作使用总结
2014/07/18 Javascript
JavaScript获取网页表单action属性的方法
2015/04/02 Javascript
分享网页检测摇一摇实例代码
2016/01/14 Javascript
js中常用的Tab切换效果(推荐)
2016/08/30 Javascript
jQuery实现的响应鼠标移动方向插件用法示例【附源码下载】
2018/08/28 jQuery
微信小程序五子棋游戏的悔棋实现方法【附demo源码下载】
2019/02/20 Javascript
微信小程序使用wx.request请求服务器json数据并渲染到页面操作示例
2019/03/30 Javascript
基于mpvue搭建微信小程序项目框架的教程详解
2019/04/10 Javascript
vue百度地图 + 定位的详解
2019/05/13 Javascript
vue动态绑定class的几种常用方式小结
2019/05/21 Javascript
原生JS实现列表内容自动向上滚动效果
2019/05/22 Javascript
node实现简单的增删改查接口实例代码
2019/08/22 Javascript
解决layui富文本编辑器图片上传无法回显的问题
2019/09/18 Javascript
Python写的服务监控程序实例
2015/01/31 Python
Python开发微信公众平台的方法详解【基于weixin-knife】
2017/07/08 Python
对python 矩阵转置transpose的实例讲解
2018/04/17 Python
TensorFlow实现自定义Op方式
2020/02/04 Python
使用Python爬取弹出窗口信息的实例
2020/03/14 Python
CSS3不透明度实例讲解
2016/04/26 HTML / CSS
HTML5 Canvas基本线条绘制的实例教程
2016/03/17 HTML / CSS
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
ORLY官网:美国专业美甲一线品牌
2019/12/11 全球购物
Eton丹麦官网:精美的男式衬衫
2020/05/27 全球购物
校园餐饮创业计划书
2014/01/10 职场文书
酒店保安员岗位职责
2014/01/31 职场文书
新闻报道稿范文
2015/07/23 职场文书
贷款担保书范本
2015/09/22 职场文书
如何通过简单的代码描述Angular父组件、子组件传值
2022/04/07 Javascript