JS中类或对象的定义说明

我们知道,JS是面向对象的。谈到面向对象,就不可避免的要涉及类的概念。一般像c#,java这些强类型语言都有固定的定义类的语法。而JS的不同之处在于它能使用各种方法实现自己的类和对象。一般的实现有以下几种方式:

1.工厂方式
工厂方式是指创建一个返回特定对象类型的工厂函数,示例代码如下:


代码如下:

function createCar(sColor,iDoors,iMpg)
{
   var oTempCar=new Object;
   oTempCar.color=sColor;
   oTempCar.doors=iDoors;
   oTempCar.mpg=iMpg;
   oTempCar.showColor=function()
   {
        alert(this.color);
   }
   return oTempCar;
}
var oCar1=createCar("red",4,23);
var oCar2=createCar("blue",3,25);
oCar1.showColor();
oCar2.showColor();

这种方式每次调用它的工厂函数,都会创建一个新对象。可问题在于每次生成一个新对象,都要创建新函数showColor,这使得每个对象都有自己的showColor版本,而事实上,所有的对象都共享同一个函数.为解决这个问题,开发者在工厂函数的外面定义了对象的方法,然后赋予对象一个指针指向这个这个函数,如下


代码如下:

function showColor()
{
   alert(this.color);
}
function createCar(sColor,iDoors,iMpg)
{
   var oTempCar=new Object;
   oTempCar.color=sColor;
   oTempCar.doors=iDoors;
   oTempCar.mpg=iMpg;
   oTempCar.showColor=showColor;
   return oTempCar;
}
var oCar1=createCar("red",4,23);
var oCar2=createCar("blue",3,25);
oCar1.showColor();
oCar2.showColor();

这样就不需要为每一个对象都创建自己的showColor函数,而只是创建指向这个函数的指针.这从功能上解决了问题,但是该函数却不像对象的方法。于是,引出了构造函数的方式。

2.构造函数方式
构造函数与工厂函数很相似,示例代码如下:


代码如下:

function Car(sColor,iDoors,iMpg)
{
   this.color=sColor;
   this.doors=iDoors;
   this.mpg=iMpg;
   this.showColor=function()
   {
      alert(this.color);
   }
}
var oCar1=new Car("red",4,23);
var oCar2=new Car("blue",3,25);

在构造函数中,内部无创建对象,而是使用this关键字。使用new运算符调用构造函数时,在执行第一行代码之前先创建一个对象,只有用this才能访问这个对象。但是这会遇到什么问题呢,很显然,它的每个对象也都会创建自己的showColor函数版本。为解决这个问题,引出了以下的原型方式.

3.原型方式
该方式利用了对象的prototype属性,可把它看成创建新对象所依赖的原型。这里,用空构造函数来设置类名。然后把所有的方法和属性都直接赋予prototype属性。如下:


代码如下:

function Car()
{}
Car.prototype.color="red";
Car.prototype.doors=4;
Car.prototype.mpg=23;
Car.prototype.drivers=new Array("Mike","Sue");
Car.prototype.showColor=function()
{
   alert(this.color);
}

原型方式只能直接赋值,而不能通过给构造函数传递参数初始化属性的值。在用这种方式时,会遇到两个问题,不知道大家注意到没有。第一问题是采用这种方式必须创建每个对象后才能改变属性的默认值。而不能在创建每个对象时都会直接有自己所需要的属性值。这点很讨厌。第二个问题在于属性所指的是对象的时候。函数共享不会出现任何问题,但是对象共享却会出现问题。因为每个实例一般都要实现自己的对象。

如下面:


代码如下:

var oCar1=new Car();
var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//输出 "Mike,Sue,Matt"
alert(oCar2.drivers);//输出"Mike,Sue,Matt"

因此drivers属性只是指向对象的指针,所以所有的实例事实上共享同一个对象。由于出现这这些问题,我们引出了下面的联合使用构造函数和原型方式。

4.混合的构造函数/原型方式
这种方式的思想是用构造函数定义对象的所有非函数属性(包括普通属性和指向对象的属性),用原型方式定义对象的函数属性(方法)。结果使得所有的函数都只被创建一次,而每个对象都有自己的对象属性实例。示例代码如下:


代码如下:

function Car(sColor,iDoors,iMpg)
{
   this.color=sColor;
   this.doors=iDoors;
   this.mpg=iMpg;
   this.drivers=new Array("Mike","Sue");
}
Car.prototype.showColor=function()
{
   alert(this.color);
}
var oCar1=new Car("red",4,23);
var oCar2=new Car("blue",3,25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//输出 "Mike,Sue,Matt"
alert(oCar2.drivers);//输出 "Mike,Sue"

由实例代码可知,这种方式同时解决了上一种方式的两个问题。不过,采用这种方式,仍有些开发者觉得不够完美。

5.动态原型方式
我们可知,大多数面向对象语言都对属性和方法进行了视觉上的封装。而上述方式的showColor方法却定义在了类的外面。因此,他们设计了动态原型方法。这种方式的基本思想和混合的构造函数/原型方式相同,唯一不同之处在于对象方法的位置。如下所示:


代码如下:

function Car(sColor,iDoors,iMpg)
{
   this.color=sColor;
   this.doors=iDoors;
   this.mpg=iMpg;
   this.drivers=new Array("Mike","Sue");
   if(typeof Car._initialized=="undefined")
  {
     Car.prototype.showColor=function()
     {
        alert(this.color);
     }
  }
  Car._initialized=true;
}

这种方式Car.prototype.showColor只被创建一次。这样依赖,这段代码更像其他语言中的类定义了。

6.混合工厂方式
这种方式通常是不能应该前一种方式的变通方法。它的目的是创建假构造函数,只返回另一种对象的新实例。


代码如下:

function createCar()
{
   var oTempCar=new Object;
   oTempCar.color=“red”;
   oTempCar.doors=4;
   oTempCar.mpg=23;
   oTempCar.showColor=function()
   {
        alert(this.color);
   };
   return oTempCar;
}
var car=new Car();

由于在Car()构造函数内部调用了new运算符,所以自动忽略第二个new运算符。在构造函数内部创建的对象被传递回变量var。这种方式在对象方法的内部管理方面与经典方式有着相同的问题。所以强烈建议:除非万不得已,还是避免使用这种方式。

(0)

相关推荐

  • Javascript 陷阱 window全局对象

    function Test(){ this.name='Test'; var name=2; this.show=function(){ alert(name); alert(this.name);//显示名字 } } var test=new Test();//通过构造器创建一个对象 test.show();//输出2和'Test' ,说明对象方法访问其属性时必须加this. function Test2(){ this.name='Test2'; this.show=function(){

  • Javascript创建自定义对象 创建Object实例添加属性和方法

    如下所示: 复制代码 代码如下: var person = new Object(); person.name = "Nicholas"; person.age = "29" person.job = "Software Engineer"; person.sayName = function () { alert(this.name); }; person.sayName();上面的例子创建了一个名为person的对象,并为它添加了三个属性(n

  • javascript中全局对象的isNaN()方法使用介绍

    复制代码 代码如下: <html> <head> <title>全局对象的isNaN()方法</title> <script> /* isNaN() 函数通常用于检测 parseFloat() 和 parseInt() 的结果,以判断它们表示的是否是合法的数字. 当然也可以用 isNaN() 函数来检测算数错误,比如用 0 作除数的情况. */ document.write(isNaN(123) + "<br/>"

  • javascript 对象定义方法 简单易学

    工厂模式: 初级开发者可能会这样定义对象: var obj = new Object(); obj.name = "hero"; obj.showName=function (){alert(this.name);} 这里存在一个问题就是如果我们要在多个地方用obj对象,可能在程序中类似的代码要写好多遍,于是产生了工厂方法 function createObj() { var obj = new Object(); obj.name="hero"; obj.show

  • JavaScript定义全局对象的方法示例

    本文实例讲述了JavaScript定义全局对象的方法.分享给大家供大家参考,具体如下: !function (factory) { factory(window['Hi'] = { __a: function () { console.log('Hi.__a'); }, __b: function () { console.log('Hi.__b'); }, __c: function () { console.log('Hi.__c'); } }); }(function (Hi) { if

  • js 多种变量定义(对象直接量,数组直接量和函数直接量)

    对象直接量创建一个对象: 复制代码 代码如下: var obj = {x:[1,2],y:23}; 代码跟下面是一样的. 复制代码 代码如下: var obj=new Object(); obj.x=new Array(1,2); obj.y=23; 测试: 复制代码 代码如下: for(var i in obj) alert(obj[i]); 函数直接量:它是一个表达式而不是语句. 复制代码 代码如下: (function(){})() 如下例: 复制代码 代码如下: (function(){

  • JavaScript中的全局对象介绍

    对于任何JavaScript程序,当程序开始运行时,JavaScript解释器都会初始化一个全局对象以供程序使用.这个JavaScript自身提供的全局对象的功能包括: 1.全局对象拥有一些常用的属性值.比如undefined.Infinity以及NaN. 2.全局对象拥有一些常用的属性对象.比如Math.JSON和Number对象均为该全局对象的属性. 3.全局对象提供一些全局函数供调用.比如isNaN().isFinite().parseInt()和eval()等. 4.全局对象提供一些全局

  • javascript 对象的定义方法

    JS中定义类的方式有很多种: 1.工厂方式 function Car(){    var ocar = new Object;    ocar.color = "blue";    ocar.doors = 4;    ocar.showColor = function(){     document.write(this.color)    };    return ocar;   } var car1 = Car();   var car2 = Car(); 调用此函数时将创建新对

  • Javascript 中创建自定义对象的方法汇总

    Javascript 中创建对象,可以有很多种方法. Object构造函数/对象字面量: 抛开设计模式不谈,使用最基本的方法,就是先调用Object构造函数创建一个对象,然后给对象添加属性. 复制代码 代码如下: var student = new Object();      student.name = "xiao ming";      student.age = 20;      student.getName = function () {          alert(th

  • Nodejs学习笔记之Global Objects全局对象

    一,开篇分析 在上个章节中我们学习了NodeJS的基础理论知识,对于这些理论知识来说理解是至关重要的,在后续的章节中,我们会对照着官方文档逐步学习里面的各部分模块,好了该是本文主角登台亮相的时候了,Global 让我们来看一下官方的定义: Global Objects全局对象These objects are available in all modules. Some of these objects aren't actually in the global scope but in the

  • javascript中全局对象的parseInt()方法使用介绍

    复制代码 代码如下: <html> <head> <title>全局对象的parseInt() 方法</title> <script> /* parseInt() 函数可解析一个字符串,并返回一个整数. 1.解析字符串,直到不能解析为止 2.进制转化中,解析字符串,直到不能解析为止 */ document.write(parseInt("123") + "<br/>");//123 docume

  • 浅析JavaScript中两种类型的全局对象/函数

    这里所说的JavaScript指浏览器环境中的包括宿主环境在内的.第一种是ECMAScript Global Object,第二种是宿主环境(Host)下的全局对象/函数. 一.核心JavaScript内置对象,即ECMAScript实现提供的不依赖于宿主环境的对象 这些对象在程序执行之前就已经(实例化)存在了.ECMAScript称为The Global Object,分为以下几种 1, 值属性的全局对象(Value Properties of the Global Object).有NaN,

随机推荐