详解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调用Session的实现代码
Oct 29 Javascript
jQuery实现的手机发送验证码倒计时效果代码分享
Aug 24 Javascript
JAVA中截取字符串substring用法详解
Apr 14 Javascript
axios发送post请求springMVC接收不到参数的解决方法
Mar 05 Javascript
vue-cli与webpack处理静态资源的方法及webpack打包的坑
May 15 Javascript
原生js实现的移动端可拖动进度条插件功能详解
Aug 15 Javascript
Js on及addEventListener原理用法区别解析
Jul 11 Javascript
JS如何实现封装列表右滑动删除收藏按钮
Jul 23 Javascript
javascript如何使用函数random来实现课堂随机点名方法详解
Jul 28 Javascript
vue实现简易图片左右旋转,上一张,下一张组件案例
Jul 31 Javascript
Vue 防止短时间内连续点击后多次触发请求的操作
Nov 11 Javascript
javascript实现移动端轮播图
Dec 09 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 文章采集正则代码
2009/12/28 PHP
深入解析php中的foreach函数
2013/08/31 PHP
php自定义函数实现二维数组按指定key排序的方法
2016/09/29 PHP
有关JavaScript的10个怪癖和秘密分享
2011/08/28 Javascript
javascript开发随笔一 preventDefault的必要
2011/11/25 Javascript
Javascript的&amp;&amp;和||的另类用法
2014/07/23 Javascript
AngularJS HTML编译器介绍
2014/12/06 Javascript
JavaScript实现表格快速变色效果代码
2015/08/19 Javascript
微信小程序页面间值传递的两种方法
2018/11/26 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
2019/01/27 jQuery
jquery 键盘事件 keypress() keydown() keyup()用法总结
2019/10/23 jQuery
[00:43]DOTA2小紫本全民票选福利PA至宝全方位展示
2014/11/25 DOTA
Python爬虫实现百度图片自动下载
2018/02/04 Python
python得到qq句柄,并显示在前台的方法
2018/10/14 Python
实例详解Python模块decimal
2019/06/26 Python
python卸载后再次安装遇到的问题解决
2019/07/10 Python
python 进程 进程池 进程间通信实现解析
2019/08/23 Python
查看已安装tensorflow版本的方法示例
2020/04/19 Python
Python OpenCV去除字母后面的杂线操作
2020/07/05 Python
HTML5 实现一个访问本地文件的实例
2012/12/13 HTML / CSS
HTML5样式控制示例代码
2013/11/27 HTML / CSS
HTML5 Canvas 实现圆形进度条并显示数字百分比效果示例
2017/08/18 HTML / CSS
详解HTML5中CSS外观属性
2020/09/10 HTML / CSS
美国第二大团购网站:LivingSocial
2016/07/24 全球购物
英国高级百货公司:Harvey Nichols
2017/01/29 全球购物
斯洛伐克最大的婴儿食品和用品网上商店:Feedo.sk
2020/12/21 全球购物
利用指针变量实现队列的入队操作
2012/04/07 面试题
C#如何允许一个类被继承但是避免这个类的方法被重载?
2015/02/24 面试题
党的群众路线教育学习材料
2014/05/12 职场文书
谢师宴答谢词
2015/01/05 职场文书
小升初自荐信怎么写
2015/03/26 职场文书
承诺书范本大全
2015/05/04 职场文书
追悼会答谢词范文
2015/09/29 职场文书
2016秋季运动会前导词
2015/11/25 职场文书
教你用Python matplotlib库制作简单的动画
2021/06/11 Python
Rust中的Struct使用示例详解
2022/08/14 Javascript