详解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 相关文章推荐
jQuery的实现原理的模拟代码 -2 数据部分
Aug 01 Javascript
关于使用 jBox 对话框的提交不能弹出问题解决方法
Nov 07 Javascript
jquery复选框全选/取消示例
Dec 30 Javascript
js对图片base64编码字符串进行解码并输出图像示例
Mar 17 Javascript
js代码实现随机颜色的小方块
Jul 30 Javascript
javascript实现数组内值索引随机化及创建随机数组的方法
Aug 10 Javascript
3种js实现string的substring方法
Nov 09 Javascript
基于JavaScript实现定时跳转到指定页面
Jan 01 Javascript
VUEJS实战之构建基础并渲染出列表(1)
Jun 13 Javascript
JavaScript触发onScroll事件的函数节流详解
Dec 14 Javascript
vue生命周期实例小结
Aug 15 Javascript
js实现鼠标点击页面弹出自定义文字效果
Dec 24 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为php增加openssl模块的方法
2011/06/14 PHP
php中长文章分页显示实现代码
2012/09/29 PHP
PHP实现邮件群发的源码
2013/06/18 PHP
ThinkPHP3.1新特性之多层MVC的支持
2014/06/19 PHP
使用PHP进行微信公众平台开发的示例
2015/08/21 PHP
PHP+Mysql+jQuery实现发布微博程序 php篇
2015/10/15 PHP
javascript 播放器 控制
2007/01/22 Javascript
js常用代码段收集
2011/10/28 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
2013/11/08 Javascript
JQuery页面地址处理插件jqURL详解
2015/05/03 Javascript
javascript组合使用构造函数模式和原型模式实例
2015/06/04 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
2015/09/17 Javascript
JS实现iframe编辑器光标位置插入内容的方法(兼容IE和Firefox)
2016/06/24 Javascript
AngularJS 模块详解及简单实例
2016/07/28 Javascript
Node.js用readline模块实现输入输出
2016/12/16 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
2017/01/13 Javascript
基于vue.js轮播组件vue-awesome-swiper实现轮播图
2017/03/17 Javascript
javascript数组去重常用方法实例分析
2017/04/11 Javascript
微信小程序实现缓存根据不同的id来进行设置和读取缓存
2017/06/12 Javascript
jquery图片预览插件实现方法详解
2019/07/18 jQuery
Vue(定时器)解决mounted不能获取到data中的数据问题
2020/07/30 Javascript
vant-ui组件调用Dialog弹窗异步关闭操作
2020/11/04 Javascript
java直接调用python脚本的例子
2014/02/16 Python
python使用正则表达式提取网页URL的方法
2015/05/26 Python
Python运行报错UnicodeDecodeError的解决方法
2016/06/07 Python
基于DATAFRAME中元素的读取与修改方法
2018/06/08 Python
python使用opencv实现马赛克效果示例
2019/09/28 Python
keras-siamese用自己的数据集实现详解
2020/06/10 Python
python+opencv实现车道线检测
2021/02/19 Python
客服实习的个人自我鉴定
2013/10/20 职场文书
安全检查与奖惩制度
2014/01/23 职场文书
《太阳》教学反思
2014/02/21 职场文书
2015届本科毕业生自我鉴定
2014/09/27 职场文书
公安机关纪律作风整顿剖析
2014/10/10 职场文书
2016年感恩教师节活动总结
2016/04/01 职场文书
spring项目中切面及AOP的使用方法
2021/06/26 Java/Android