详解JavaScript基于面向对象之创建对象(1)


Posted in Javascript onDecember 10, 2015

这一次我们深入的学习一下JavaScript面向对象技术,在学习之前,必要的说明一下一些面向对象的一些术语。这也是所有面对对象语言所拥有的共同点。有这样几个面向对象术语:
一、对象
       ECMA-262把对象(object)定义为“属性的无序集合,每个属性存放一个原始值、对象或函数”。严格来说,这意味着对象是无特定顺序的值的数组。尽管ECMAScript如此定义对象,但它更通用的定义是基于代码的名词(人、地点或事物)的表示。
二、类
       每个对象都由类定义,可以把类看做对象的配方。类不仅要定义对象的接口(interface)(开发者访问的属性和方法),还要定义对象的内部工作(使属性和方法发挥作用的代码)。编译器和解释程序都根据类的说明构建对象。
三、实例
       程序使用类创建对象时,生成的对象叫作类的实例(instance)。对类生成的对象的个数的唯一限制来自于运行代码的机器的物理内存。每个实例的行为相同,但实例处理一组独立的数据。由类创建对象实例的过程叫做实例化(instantiation)。
       在前面的章节我们提到过,ECMAScript并没有正式的类。相反,ECMA-262把对象定义描述为对象的配方。这是 ECMAScript逻辑上的一种折中方案,因为对象定义实际上是对象自身。即使类并不真正存在,我们也把对象定义叫做类,因为大多数开发者对此术语更熟悉,而且从功能上说,两者是等价的。
       使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的对象。ECMAScript 拥有很多创建对象的方法。
1、原始方式
       因为对象的属性可以在对象创建后动态定义,所有许多开发者都在JavaScript 最初引入时编写类似下面的代码:

var Car = new Object(); 
Car.color = "blue"; 
Car.doors = 4; 
Car.mpg = 25; 
Car.showColor = function() { 
  return this.color; 
}; 
document.write(Car.showColor());//输出:blue

       在上面的代码中,创建对象Car。然后给它设置几个属性:它的颜色是蓝色,有四个门,每加仑油可以跑 25 英里。最后一个属性实际上是指向函数的指针,意味着该属性是个方法。执行这段代码后,就可以使用对象Car。不过这里有一个问题,就是可能需要创建多个Car的实例,这样就造成了我们会重复许多类似的代码,这样会很麻烦。
2、工厂方式
       要解上述的多个类似对象声明的问题,开发者创造了能创建并返回特定类型的对象的工厂方式。这种方式就是为了解决实例化对象产生大量重复的问题。
(1)无参数的工厂方式
       例如,函数createCar()可用于封装前面列出的创建Car对象的操作:

function createCar() { 
var TempCar = new Object(); 
TempCar.color = "blue"; 
TempCar.doors = 4; 
TempCar.mpg = 25; 
TempCar.showColor = function() { 
    return this.color; 
 }; 
 return TempCar; 
}; 
var Car1 = createCar(); 
var Car2 = createCar(); 
document.write(Car1.showColor()+"<br/>");//输出:blue 
document.write(Car2.showColor());//输出:blue

       在这里,第一个例子中的所有代码都包含在createCar()函数中。此外,还有一行额外的代码,返回TempCar 对象作为函数值。调用此函数,将创建新对象,并赋予它所有必要的属性,复制出一个我们在前面说明过的Car对象。因此,通过这种方法,我们可以很容易地创建Car对象的两个版本(Car1和 Car2),它们的属性完全一样。
(2)有参数的工厂方式
       我们还可以修改createCar()函数,给它传递各个属性的默认值,而不是简单地赋予属性默认值:

function createCar(Color,Doors,Mpg) { 
 var TempCar = new Object(); 
 TempCar.color = Color; 
 TempCar.doors = Doors; 
 TempCar.mpg = Mpg; 
 TempCar.showColor = function() { 
    return this.color; 
 }; 
 return TempCar; 
}; 
var Car1 = createCar("red",4,23); 
var Car2 = createCar("blue",3,25); 
document.write(Car1.showColor()+"<br/>");//输出:red 
document.write(Car2.showColor());//输出:blue

       给createCar()函数加上参数,即可为要创建的Car对象的color、doors 和mpg属性赋值。这使两个对象具有相同的属性,却有不同的属性值。
       工厂方式解决了重复实例化的问题,但是还是有一个问题,那就是前面的例子中,每次调用函数createCar(),都要创建新函数showColor(),意味着每个对象都有自己的 showColor() 版本。而事实上,每个对象都共享同一个函数。有些开发者在工厂函数外定义对象的方法,然后通过属性指向该方法,从而避免这个问题:

function showColor() { 
   return this.color; 
}; 
function createCar(Color,Doors,Mpg) { 
 var TempCar = new Object(); 
 TempCar.color = Color; 
 TempCar.doors = Doors; 
 TempCar.mpg = Mpg; 
 TempCar.showColor = showColor; 
 return TempCar; 
}; 
var Car1 = createCar("red",4,23); 
var Car2 = createCar("blue",3,25); 
document.write(Car1.showColor()+"<br/>");//输出:red 
document.write(Car2.showColor());//输出:blue

       在上面这段重写的代码中,在函数 createCar()之前定义了函数 showColor()。在createCar()内部,赋予对象一个指向已经存在的 showColor() 函数的指针。从功能上讲,这样解决了重复创建函数对象的问题;但是从语义上讲,该函数不太像是对象的方法。所有这些问题都引发了开发者定义的构造函数的出现。
3、构造函数方式
       创建构造函数就像创建工厂方式的函数一样容易。第一步选择构造函数的名字。根据惯例,这个名字的首字母大写,以使它与首字母通常是小写的变量名分开。除了这点不同,构造函数看起来很像工厂方式的函数。请看下面的例子:

function Car(Color,Doors,Mpg) { 
 this.color = Color; 
 this.doors = Doors; 
 this.mpg = Mpg; 
 this.showColor = function() { 
    return this.color; 
 }; 
}; 
var Car1 = new Car("red",4,23); 
var Car2 = new Car("blue",3,25); 
document.write(Car1.showColor()+"<br/>");//输出:red 
document.write(Car2.showColor());//输出:blue

       下面为您解释上面的代码与工厂方式的差别。首先在构造函数内没有创建对象,而是使用this关键字。使用new运算符构造函数时,在执行第一行代码前先创建一个对象,只有用this才能访问该对象。然后可以直接赋予this属性,默认情况下是构造函数的返回值(不必明确使用 return 运算符)。现在,用new运算符和对象名Car创建对象,就更像 ECMAScript 中一般对象的创建方式了。
      就像工厂方式的函数,构造函数会重复生成函数,为每个对象都创建独立的函数版本。不过,与工厂方式的函数相似,也可以用外部函数重写构造函数,同样地,这么做语义上无任何意义。这正是下面要讲的原型方式的优势所在。在下篇文章中会详细的分析面向对象的原型方式以及其他综合的方式。

以上就是本文的全部内容,希望对大家的学习javascript程序设计有所帮助。

Javascript 相关文章推荐
laytpl 精致巧妙的JavaScript模板引擎
Aug 29 Javascript
js给网页加上背景音乐及选择音效的方法
Mar 03 Javascript
js一维数组、多维数组和对象的混合使用方法
Apr 03 Javascript
jQuery的promise与deferred对象在异步回调中的作用
May 03 Javascript
使用jQuery判断浏览器滚动条位置的方法
May 30 Javascript
多种方式实现js图片预览
Dec 12 Javascript
微信小程序 扎金花简单实例
Feb 21 Javascript
Node.js 使用命令行工具检查更新
Jun 08 Javascript
微信小程序实现自上而下字幕滚动
Jul 14 Javascript
vue中uni-app 实现小程序登录注册功能
Oct 12 Javascript
从Node.js事件触发器到Vue自定义事件的深入讲解
Jun 26 Javascript
前端开发基础javaScript的六大作用
Aug 06 Javascript
AngularJs实现ng1.3+表单验证
Dec 10 #Javascript
理解AngularJs指令
Dec 10 #Javascript
详解AngularJS实现表单验证
Dec 10 #Javascript
jquery实现鼠标悬浮停止轮播特效
Aug 20 #Javascript
JavaScript动态创建form表单并提交的实现方法
Dec 10 #Javascript
jquery实现定时自动轮播特效
Dec 10 #Javascript
jQuery手动点击实现图片轮播特效
Apr 20 #Javascript
You might like
php中检查文件或目录是否存在的代码小结
2012/10/22 PHP
ThinkPHP的L方法使用简介
2014/06/18 PHP
php+lottery.js实现九宫格抽奖功能
2019/07/21 PHP
laradock环境docker-compose操作详解
2019/07/29 PHP
laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
2019/10/08 PHP
js 数组克隆方法 小结
2010/03/20 Javascript
使用Firebug对js进行断点调试的图文方法
2011/04/02 Javascript
JQuery for与each性能比较分析
2013/05/14 Javascript
弹出窗口并且此窗口带有半透明的遮罩层效果
2014/03/13 Javascript
js中的for如何实现foreach中的遍历
2014/05/31 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
纯js代码实现未知宽高的元素在指定元素中垂直水平居中显示
2015/09/12 Javascript
prototype与__proto__区别详细介绍
2017/01/09 Javascript
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
利用Blob进行文件上传的完整步骤
2018/08/02 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
2018/08/10 Javascript
layui动态加载多表头的实例
2019/09/05 Javascript
layui点击数据表格添加或删除一行的例子
2019/09/12 Javascript
vue.js实现二级菜单效果
2019/10/19 Javascript
Vue获取微博授权URL代码实例
2020/11/04 Javascript
JavaScript对象访问器Getter及Setter原理解析
2020/12/08 Javascript
[04:45]DOTA2-DPC中国联赛正赛 iG vs LBZS 赛后选手采访
2021/03/11 DOTA
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
2016/06/02 Python
老生常谈Python进阶之装饰器
2017/05/11 Python
如何使用Python破解ZIP或RAR压缩文件密码
2020/01/09 Python
python目标检测给图画框,bbox画到图上并保存案例
2020/03/10 Python
python库skimage给灰度图像染色的方法示例
2020/04/27 Python
python excel多行合并的方法
2020/12/09 Python
快速创建 HTML5 Canvas 电信网络拓扑图的示例代码
2018/03/21 HTML / CSS
中国跨境在线时尚零售商:Bellelily
2018/04/06 全球购物
俄罗斯卫浴采暖及维修用品超级市场:Dkrussia
2020/05/12 全球购物
水利水电专业自荐信
2014/07/08 职场文书
2016暑期社会实践心得体会范文
2016/01/14 职场文书
幼儿园教学反思范文
2016/03/02 职场文书
Mysql 用户权限管理实现
2021/05/25 MySQL
只用20行Python代码实现屏幕录制功能
2021/06/02 Python