详解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 相关文章推荐
Apply an AutoFormat to an Excel Spreadsheet
Jun 12 Javascript
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
May 15 Javascript
EasyUI中的tree用法介绍
Nov 01 Javascript
字符串反转_JavaScript
Apr 28 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
Jun 12 Javascript
前端弹出对话框 js实现ajax交互
Sep 09 Javascript
js实现1,2,3,5数字按照概率生成
Sep 12 Javascript
vue-cli开发时,关于ajax跨域的解决方法(推荐)
Feb 03 Javascript
Node.js进阶之核心模块https入门
May 23 Javascript
JS实现获取进今年第几天是周几的方法分析
Jun 27 Javascript
JS实现水平遍历和嵌套递归操作示例
Aug 15 Javascript
javascript+css实现进度条效果
Mar 25 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学习之输出字符串(echo,print,printf,print_r和var_dump)
2011/04/17 PHP
基于php socket(fsockopen)的应用实例分析
2013/06/02 PHP
zf框架的Filter过滤器使用示例
2014/03/13 PHP
C#静态方法与非静态方法实例分析
2014/09/22 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
2015/11/15 PHP
在WordPress中使用wp-cron插件来设置定时任务
2015/12/10 PHP
JQUERY 对象与DOM对象之两者相互间的转换
2009/04/27 Javascript
Javascript获取窗口(容器)的大小及位置参数列举及简要说明
2012/12/09 Javascript
PHP中CURL的几个经典应用实例
2015/01/23 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
2015/02/13 Javascript
jQuery ajaxForm()的应用
2016/10/14 Javascript
解决拦截器对ajax请求的拦截实例详解
2016/12/21 Javascript
详解Vuejs2.0 如何利用proxyTable实现跨域请求
2017/08/03 Javascript
Vue中引入样式文件的方法
2017/08/18 Javascript
深入浅析JS中的严格模式
2018/06/04 Javascript
详解原生JS回到顶部
2019/03/25 Javascript
详细教你微信公众号正文页SVG交互开发技巧
2019/07/25 Javascript
基于Python 的进程管理工具supervisor使用指南
2016/09/18 Python
Django接受前端数据的几种方法总结
2016/11/04 Python
Python实现PS滤镜功能之波浪特效示例
2018/01/26 Python
Python 内置函数进制转换的用法(十进制转二进制、八进制、十六进制)
2018/04/30 Python
基于Python列表解析(列表推导式)
2018/06/23 Python
Python中的__init__作用是什么
2020/06/09 Python
Pycharm导入anaconda环境的教程图解
2020/07/31 Python
Html5定位终极解决方案
2020/02/05 HTML / CSS
Skyscanner阿联酋:全球领先的旅游搜索平台
2017/11/25 全球购物
CHARLES & KEITH英国官网:新加坡时尚品牌
2018/07/04 全球购物
综合内勤岗位职责
2014/04/14 职场文书
村道德模范事迹材料
2014/08/28 职场文书
2014年店长工作总结
2014/11/17 职场文书
小学生反邪教心得体会
2016/01/15 职场文书
golang中切片copy复制和等号复制的区别介绍
2021/04/27 Golang
解决python绘图使用subplots出现标题重叠的问题
2021/04/30 Python
MySQL sql_mode的使用详解
2021/05/08 MySQL
Github 使用python对copilot做些简单使用测试
2022/04/14 Python
vue.js 使用原生js实现轮播图
2022/04/26 Vue.js