详解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 相关文章推荐
JavaScript Undefined,Null类型和NaN值区别
Oct 22 Javascript
javascript 节点排序 2
Jan 31 Javascript
js Array对象的扩展函数代码
Apr 24 Javascript
jquery判断元素的子元素是否存在的示例代码
Feb 04 Javascript
javascript制作的cookie封装及使用指南
Jan 02 Javascript
跟我学习javascript的严格模式
Nov 16 Javascript
javascript加减乘除的简单实例
Jul 12 Javascript
微信小程序picker组件下拉框选择input输入框的实例
Sep 20 Javascript
Vue2.0 slot分发内容与props验证的方法
Dec 12 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
Jun 24 Javascript
Vue axios 将传递的json数据转为form data的例子
Oct 29 Javascript
开发Node CLI构建微信小程序脚手架的示例
Mar 27 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
PHP4之COOKIE支持详解
2006/10/09 PHP
php中如何同时使用session和cookie来保存用户登录信息
2013/07/05 PHP
php读取excel文件示例分享(更新修改excel)
2014/02/27 PHP
Chrome Web App开发小结
2014/09/04 PHP
php函数重载的替代方法--伪重载详解
2015/05/08 PHP
php使用number_format函数截取小数的方法分析
2016/05/27 PHP
PHP实现网站访问量计数器
2017/10/27 PHP
用javascript将数据库中的TEXT类型数据动态赋值到TEXTAREA中
2007/04/20 Javascript
JavaScript Prototype对象
2009/01/07 Javascript
使用Chrome调试JavaScript的断点设置和调试技巧
2014/12/16 Javascript
原生javaScript实现图片延时加载的方法
2014/12/22 Javascript
JavaScript修改浏览器tab标题小技巧
2015/01/06 Javascript
jquery+ajax+text文本框实现智能提示完整实例
2016/07/09 Javascript
JS获取鼠标选中的文字
2016/08/10 Javascript
利用JS轻松实现获取表单数据
2016/12/06 Javascript
浅析js的模块化编写 require.js
2016/12/07 Javascript
在vue.js中抽出公共代码的方法示例
2017/06/08 Javascript
微信小程序 实现点击添加移除class
2017/06/12 Javascript
vue2.5.2使用http请求获取静态json数据的实例代码
2018/02/27 Javascript
详解Vue的钩子函数(路由导航守卫、keep-alive、生命周期钩子)
2018/07/24 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
2018/09/11 Javascript
react 应用多入口配置及实践总结
2018/10/17 Javascript
Python编程实现及时获取新邮件的方法示例
2017/08/10 Python
python numpy函数中的linspace创建等差数列详解
2017/10/13 Python
Python中static相关知识小结
2018/01/02 Python
python对execl 处理操作代码
2020/06/22 Python
彪马西班牙官网:PUMA西班牙
2019/06/18 全球购物
生产内勤岗位职责
2013/12/07 职场文书
给校长的建议书200字
2014/05/16 职场文书
工作失职检讨书(精华篇)
2014/10/15 职场文书
校长师德表现自我评价
2015/03/04 职场文书
2015年医院药剂科工作总结
2015/05/04 职场文书
同意转租证明
2015/06/24 职场文书
2016年过年放假安排通知
2015/08/18 职场文书
门面租赁合同范文
2019/08/06 职场文书
排查并解决MySQL生产库内存使用率高的报警
2022/04/11 MySQL