JavaScript中对象的创建方式

面向对象的语言有一个标志,那就是都有类的概念,通过类可以创建任意多个具有相同属性和方法的对象。

在JavaScript中,没有类的概念,因此JavaScript中的对象和基于类的语言中的对象也是不同的。

在JavaScript中,对象是“无序属性的集合,其属性可以包含基本值、对象或者函数”。对象本质是值,就是一组没有特定顺序的值。其中值可以是数据,也可以是函数。

每个对象都是基于一个引用类型创建的,这个引用类型可以是JavaScript中定义的原生类型也可以是自定义的类型。

创建自定义的对象最简单的方式是先创建一个Object对象,然后再为该对象添加自定义的属性和方法。看下面的例子。

var apple = new Object();

apple.color = red;

apple.name = "红富士";

apple.sayHello = function (){

         alert("我是一颗红富士苹果。");

};

以上创建了一个名字为apple的对象,apple对象除了拥有Object类型自带的属性之外,还拥有自己特有的属性和方法,分别是color、name属性和sayHello方法。

此外,上面例子中创建的对象还可以用对象字面量语法写成如下形式。

var apple ={

         color:"red";

         name:"红富士";

         sayHello:function(){

                   alert("我是一颗红富士苹果。");

         };

};

从上面的例子可以看出,虽然利用Object构造函数或对象字面量十分方便,但是如果需要创建多个相同的对象时,就会产生很多重复的代码,这违背了提高代码复用性的准则。

为了这个问题,可以通过以下几种模式创建对象,这些模式有自己的优缺点和使用时机。

 

工厂模式

工厂模式作为一种优秀的对象生产模式,在软件工程领域广为人知,这种模式抽象了创建对象的细节。考虑到在ECMAScript中无法创建类,开发人员可以就发明了一种函数,用函数来封装以特定接口创建对象的细节,如下所示。

function createApple(color,name){

         varo = new Object();

         o.name= name;

         o.color= color;

         o.sayHello= function(){

                   alert("我是一颗” +this.name + ”苹果。");

         };

         returno;

}


函数createApple()可以根据传入的参数创建并返回一个包含必要信息的Apple类型对象。

工厂模式虽然解决了代码的复用性问题,但是却没有解决对象的类型识别问题,即只知道该对象是Object类型,却不知道具体类型。

 

构造函数模式

利用ECMAScript中的构造函数可以创建特性类型的对象,例如Object、Array这样的原生构造函数可以创建对应类型的对象。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。可以使用构造函数模式将前面的例子重写如下。

function Apple(color,name){

         this.name= name;

         this.color= color;

         this.sayHello= function(){

                   alert("我是一颗” +this.name + ”苹果。");

         };

}


按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数应该以一个小写字母开头。这个做法借鉴自其它面向对象语言,主要是为了区别ECMAScript中的其它函数;因为构造函数本身也是函数,只不过可以用来创建对象而已。

要创建Apple的新实例,必须使用new操作符。以这种方式调用构造函数实际上会经历一下4个步骤:

         1)创建一个新对象;

         2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象);

         3)执行构造函数中的代码(为这个新对象添加属性);

         4)返回新对象。

根据构造函数创建Apple实例,并检测它们的类型。

var apple1 = newApple("red","红富士");

ar apple2 = newApple("red","阿克苏");

alert(apple1 instanceof Object);//true

alert(apple1 instanceof Apple);//true


创建自定义的构造函数意味着在必要的时候可以将它的实例标示为一种特定的类型;而这正是构造函数模式胜过工厂模式的地方。在本例中,之所以apple1和apple2既是Object的实例又是Apple的实例,是因为所有对象均继承自Object。

构造函数模式创建对象的优缺点:

构造函数模式创建对象虽然好用,也可以标示为对象的类型,但是用构造函数的主要问题就是,在利用构造函数创建对象时,每个该类型对象实例中的方法要重新创建一遍,虽然在apple1和apple2中都有一个名为sayName的方法,但是这两个方法不是同一个Function类型的实例。因为ECMAScript中的函数也是对象,因此每次定义一个函数,就是实例化了一个对象。

针对以上问题,JavaScript通过使用原型模式来解决。关于原型模式的介绍,可以关注JavaScript原型模式

使用构造函数模式和原型模式组合创建对象。

创建自定义类型的最常见方式,就是组合使用构造函数模式与原型对象模式。构造函数用于定义实例属性,而原型模式用户定义方法和实例共享的属性。结果是,每个实例中都有自己独一无二的实例属性,但同时又享有对方法的共同引用,最大限度地节省了内存。另外,这种模式还支持向构造函数传递参数;集两种模式之长。实例如下:

function Apple(name){

         this.name= name;

}

Apple.prototype = {

         constructor:Apple,//指定constructor属性指向该原型属性所属的函数

         color:"red",

         sayName:function(){

                   alert("我是一颗" +this.name + "苹果。");

         }

};

var apple1 = new Apple("红富士");

var apple2 = new Apple("阿克苏");

alert(apple1.name);//红富士

alert(apple2.name);//阿克苏

alert(apple1.color);//red

alert(apple2.color);//red

apple1.sayName();//我是一颗红富士苹果。

apple2.sayName();//我是一颗阿克苏苹果。


在这个例子中,实例属性都是在构造函数中定义的,而由实例共享的color属性、constructor属性、sayName方法则是在原型中定义的。这样一来,每个对象都有自己独一无二的名字,修改了名字,并不影响其他的实例。

组合使用构造函数模式与原型对象模式是目前在ECMAScript中使用最广泛、认同度最高的一种创建自定义的方法。可以说是用来定义引用类型的一种默认模式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值