《HTML5 Canvas游戏开发实战》——1.6 JavaScript中的面向对象

简介:

本节书摘来自华章计算机《HTML5 Canvas游戏开发实战》一书中的第1章,第1.6节,作者:张路斌著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.6 JavaScript中的面向对象

在本章开始的时候就已经说了,对于游戏开发来说,使用面向对象的方法进行编程是很有必要的。所以在介绍游戏开发之前,先来了解一下如何使用JavaScript进行面向对象的编程。可以说,JavaScript是一种基于对象的语言,但是,它又不是一种真正的面向对象的编程语言,因为它的语法中不存在class(类)。本节将分析和解决如何在JavaScript中实现封装和继承等面向对象的问题。
1.6.1 类
JavaScript对象很抽象,所以下面将以实际的例子来解释如何定义一个简单的类。以下是一个没有任何属性和方法的类的定义:
function MyClass(){};
你可能会想,这不就是个简单函数的声明吗?没错,这个函数就是一个类的定义的实现。如何使用这个类呢?看下面的代码:

var cls1 = new MyClass();

这样,利用new就可以生成MyClass的一个实例了。所以,在JavaScript中,可以说函数就是类,类就是函数。
我们知道,一个实例的封装包含属性和方法的封装。那么如何实现呢?接着看下面的代码:

function MyClass(name,age){
    this.name = name;
    this.age = age;
};
var cls1 = new MyClass("lufy",10);
alert(cls1.name + ":" + cls1.age);//[lufy:10]

从上面的代码可以看出,在函数内使用this就能给函数本身增加属性值。而在上面的代码中就给MyClass函数增加了name和age两个属性。
同样,还可以利用this给这个类增加一个toString方法,代码如下:

function MyClass(name,age){
    this.name = name;
    this.age = age;
    this.toString() = function(){
        alert(this.name + ":" + this.age);
    };
};
var cls1 = new MyClass("lufy",10);
cls1.toString();//[lufy:10]

经过测试可以发现,我们已经成功地给MyClass增加了toString方法。另外,也可以用以下代码来添加方法:

function MyClass(name,age){
    this.name = name;
    this.age = age;
};
var cls1 = new MyClass("lufy",10);
cls1.toString() = function(){
    alert(this.name + ":" + this.age);
};
cls1.toString();//[lufy:10]

虽然这样也能给这个类添加一个方法,但需要注意的是,这种方式只是给cls1这个实例增加了方法,并未给MyClass本身增加方法。比如,下面的代码会出错:

function MyClass(name,age){
    this.name = name;
    this.age = age;
};
var cls1 = new MyClass("lufy",10);
cls1.toString() = function(){
    alert(this.name + ":" + this.age);
};
cls1.toString();//[lufy:10]
var cls2 = new MyClass("legend",12);
cls2.toString();//报错

出错的原因是cls2内并不存在toString方法。可见想要通过这种方式来给一个类的本身增加方法是行不通的。要想给MyClass类的本身增加方法,需要将方法定义在MyClass这个函数的内部,这样的话,每声明一个新的实例,就会将MyClass本身复制一遍。但是,如果MyClass类里包含十几个或几十个方法,那么每次都得把这些方法复制一遍,这显然不是最优的做法。
既然不能将一个类(函数)所包含的方法都定义在函数的内部,那么,如何来给一个类添加方法呢?这就需要用到函数的prototype属性了。每一个函数都会包含一个prototype属性,这个属性指向了一个prototype对象,我们可以指定函数对应的prototype对象。如果不指定,则函数的prototype属性将指向一个默认的prototype对象,并且此默认prototype对象的constructor属性又会指向该函数。
当用构造函数创建一个新的对象时,新的对象会获取构造函数的prototype属性所指向的prototype对象的所有属性和方法,这样一来,构造函数对应的prototype对象所做的任何操作都会反映到它所生成的对象上,所有的这些对象将共享与构造函数对应的prototype对象的属性和方法。
虽然新创建的对象可以使用它的构造函数所指向的prototype对象的属性和方法,但不能像构造函数那样直接调用prototype对象(对象没有prototype属性)。
简而言之,就是如果我们使用函数的prototype对象来给函数添加方法,那么在创建一个新的对象的时候,并不会复制这个函数的所有方法,而是指向了这个函数的所有方法。
具体的实现方法参看下面的代码:

function MyClass(name,age){
    this.name = name;
    this.age = age;
};
MyClass.prototype.toString = function(){
    alert(this.name + ":" + this.age);
}
var cls1 = new MyClass("lufy",10);
cls1.toString();//[lufy:10]
var cls2 = new MyClass("legend",12);
cls2.toString();//[legend:12]

对于prototype对象来说,由于存在的是指向的关系,所以避免了不必要的浪费,如图1-10所示。

image

如果要加入多个方法,也可以使用下面的方式:

function MyClass(name,age){
    this.name = name;
    this.age = age;
};
MyClass.prototype = {
    toString:function(){
        alert(this.name + ":" + this.age);
    },
    sayHellow:function(){
        alert(this.name + ",你好!");
    }
};

var cls1 = new MyClass("lufy",10);
cls1.toString();//[lufy:10]
cls1.sayHellow ();//[lufy,你好!]

这就是JavaScript中给类添加方法的实现,它是利用prototype来实现封装的。
1.6.2 静态类
那么,JavaScript中的静态类又是如何实现的呢?其实下面的函数本身就可以当作静态类来用:

var StaticClass = function(){};
StaticClass.name = "StaticName";
StaticClass.Sum = function(value1,value2){
return value1 + value2;
};
alert(StaticClass.name);//[StaticName]
alert(StaticClass.Sum(1,3));//[4]

这样,在使用静态类的时候,就无须创建新的实例了,可直接用“类名+点+属性或方法”的方式。
1.6.3 继承
上面只讲了类的封装,那么如何实现类的继承呢?如有如下两个构造函数:

function PeopleClass(){
    this.type = "人";
};
PeopleClass.prototype = {
    getType:function(){
        alert("这是一个人");
    }
};
function StudentClass(name,sex){
    this.name = name;
    this.sex = sex;
};

如何让“学生”对象来继承“人”对象呢?可使用apply方法将父对象的构造函数绑定在子对象上,代码如下:

function PeopleClass(){
    this.type = "人";
};
PeopleClass.prototype = {
    getType:function(){
        alert("这是一个人");
    }
};
function StudentClass(name,sex){
    PeopleClass.apply(this, arguments);
    this.name = name;
    this.sex = sex;
};
var stu = new StudentClass("lufy","男");
alert(stu.type);//[人]

从运行结果来看,StudentClass继承了PeopleClass的属性“人”。
而方法的继承,只要循环使用父对象的prototype进行复制,即可达到继承的目的。具体方法如下:

function PeopleClass(){
    this.type = "人";
};
PeopleClass.prototype = {
    getType:function(){
        alert("这是一个人");
    }
};
function StudentClass(name,sex){
    PeopleClass.apply(this, arguments);
    var prop;
    for(prop in PeopleClass.prototype){
        var proto = this.constructor.prototype;
        if(!proto[prop]){
            proto[prop] = PeopleClass.prototype[prop];
        }
        proto[prop]["super"] = PeopleClass.prototype;
    }
    this.name = name;
    this.sex = sex;
};
var stu = new StudentClass("lufy","男");
alert(stu.type);//[人]
stu.getType();//[这是一个人]

以上,就是JavaScript中继承的实现。了解了这些知识后,就可以在JavaScript中使用面向对象的方法了,这对于提高开发效率是很有帮助的。

相关文章
|
人工智能 自然语言处理 JavaScript
通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
通义灵码基于自然语言需求,快速生成完整Vue组件。例如,用Vue 2和JavaScript实现贪吃蛇游戏:包含键盘控制、得分系统、游戏结束判定与Canvas动态渲染。AI生成的代码符合规范,支持响应式数据与事件监听,还能进阶优化(如增加启停按钮、速度随分数提升)。传统需1小时的工作量,使用通义灵码仅10分钟完成,大幅提升开发效率。操作简单:安装插件、输入需求、运行项目即可实现功能。
654 4
 通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
|
12月前
|
开发框架 JavaScript 前端开发
精选HTML、JavaScript、ASP代码片段集锦
这些代码片段代表了HTML, JavaScript和ASP的基本应用,可被集成到更复杂的项目中。它们注重实用性,并且易于理解,旨在帮助开发者快速开始项目构建或进行学习。尽管ASP不如其他服务器端技术(如Node.js, PHP, Ruby等)现代,但它在遗留系统中仍非常普遍,了解基础仍具有价值。
402 14
|
人工智能 程序员 UED
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
931 21
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
前端开发 JavaScript
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
829 14
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
移动开发 JavaScript 前端开发
HTML5最新经典俄罗斯方块游戏插件
HTML5最新经典俄罗斯方块游戏插件
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
1267 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
html+js+css实现的建筑方块立体数字时钟源码
html+js+css实现的建筑方块立体数字时钟源码
686 33
|
移动开发 前端开发 HTML5
基于HTML5+Canvas绘制的鼠标跟随三角形碎片光标动画代码
基于HTML5+Canvas绘制的鼠标跟随三角形碎片光标动画特效代码,很有意思,一团三角形碎片跟随鼠标的移动,不冗长、不笨重,反而有一种很轻盈的感觉,非常不错
290 29
HTML在线扫雷游戏网页源码
HTML在线扫雷游戏网页源码是一款基于HTML+CSS+JavaScript开发的在线扫雷小游戏单页源码,为用户提供了一个无需安装即可在浏览器中直接玩的扫雷游戏。该游戏的源码不仅包含了完整的游戏逻辑,还具备丰富的界面设计和用户交互功能,使得玩家能够轻松上手并享受扫雷带来的乐趣。
693 22
|
移动开发 前端开发 HTML5
Html5 Canvas绘制圆形仪表盘动画源码
Html5 Canvas绘制圆形仪表盘动画特效是一款基于HTML5 Canvas绘制的圆形百分比仪表盘动画特效。
275 1