面向对象语言有一个非常显著的标志,那就是它们都有类的概念,通过类之间的继承就可以达到任意创建具有相同属性方法的对象。而在ECMAScript中并没有类的概念,它把对象定义为:无序属性的集合,其属性包含基本值、对象或者函数。这也意味着对象的每个属性或者方法都有一个名字,每个NAME对应一个VALUE,我们可以通过这些NAME来访问对应的VALUE。那么我们怎么创建这些对象呢?下面具体阐述一下七中对象创建方法。

1.工厂模式

工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程。考虑到ECMAScript中并没有类的概念,开发人员就采用创建一个函数,再用这个函数以特定接口创建对象的细节。示例如下:

function createPerson(name,age,job){
var p=new Object();
p.name=name;
p.age=age;
p.job=job;
p.sayAge=function(){
alert(this.age);
};
return p;
}
var person=createPerson(“syf”,“23”,“stu”);

2.构造函数模式

ECMAScript中有一些原生的构造函数,例如Object,Arrary等,我们可以用它们创建对象。除此之外,我们也可以创建自定义的构造函数,来定义自定义对象类型的属性和方法。示例如下:

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayAge=function(){
alert(this.age) ;
};
}
var person=new Person("syf","23","stu");

通过对比工厂方式和构造函数方式可以看出,它们函数内部的代码有很大的相似性。但在构造函数模式里我们并没有显示的创建对象(new Object),而是直接将属性和方法赋值给了this对象,也没有使用return语句来返回结果。要想通过构造函数模式创建对象的话,那就得使用new操作符。

构造函数与其他函数的唯一区别就是调用它们的方式不同,任何函数只要通过new操作符调用,那么它就可以作为构造函数,反之则是普通函数。

3.原型模式

每个函数都有一个prototype属性,它是一个指针,指向一个对象,这个被指向的对象包含着可以被特定类型的所有实例共享的属性和方法。从字面来理解,prototype就是通过调用构造函数而创建的那个对象实例的原型对象,里面包含着对象实例共享的属性和方法。换句话说,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。示例如下:

function Person(){}
Person.prototype.name="syf";
Person.prototype.age="23";
Person.prototype.job="job";
Person.prototype.sayAge=function(){
alert(this.age);
};
var person= new Person();

由原型模式创建的对象访问的都是同一组属性和方法,所有实例在默认情况下都取得相同的属性值。对象实例可以访问原型中的属性和方法,但不能重写原型中的值。如果再实例中添加了一个与原型中同名的属性,那将在实例中创建这个属性,这个新的属性也会屏蔽掉原型中的属性和方法。这个得属性或者方法即使设置为null,也不会再恢复与原型的链接,除非我们使用delete操作符完全删除实例属性,这样才能恢复对原型中属性的访问。也可以理解为,通过原型模式创建对象实例,实例是原型的一个映射,修改实例不会反映到原型上,而原型上的改动会对实例产生影响。

4.组合使用构造函数模式和原型模式

在创建自定义类型的众多方式中,组合方式是最常用的方式。这是因为在组合模式中,我们用构造函数来定义实例属性,用原型模式来定义方法和共享的属性,最终每个实例都有自己的一份实例属性副本,同时还有共享的方法,大大节省了内存。示例如下:

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["zz","fzw"];
}
Person.prototype={
constructor:Person;
sayAge:function(){ alert(this.age);
}
}
var person=new Person("syf","23","stu");

5.动态原型模式

其本质上就是在需要的时候或者说在必要的情况下,才通过构造函数初始化原型。也可以这样理解,可以通过检查某个应该存在的方法是否有效,来决定是否初始化原型。它把所有的信息都封装在了构造函数中,也保证了使用组合模式创建对象的优势。示例如下:function Person(name,age,job){


function Person(name,age,job){
   this.name=name;
this.age=age;
this.job=job;
if(typeof this.sayAge !="function"){
Person.prototype={
sayAge:function(){ alert(this.age);}
}
}
var person=new Person("syf","23","stu");

6.寄生构造函数模式

其基本思想是创建一个函数,这个函数只用来封装创建对象的代码,然后返回创建的对象。这种方法除了使用NEW操作符创建对象之外,与工厂模式相比并没有什么区别。

function Person(name,age,job){
var p=new Object();
p.name=name;
p.age=age;
p.job=job;
p.sayAge=function(){
alert(this.age);
};
return p;
}
var person= new Person(“syf”,“23”,“stu”);

用寄生构造函数创建对象时,其返回的对象与构造函数或者与构造函数的原型属性之间没有关系。构造函数返回的对象与在构造函数外创建的对象没有什么不同,也就不能使用instanceof操作符来确定对象类型。

7.稳妥构造函数模式

所谓稳妥对象就是没有公共属性,其方法也不引用this对象。这种对象适合在一些安全环境中或者在防止数据被其他应用程序改动时使用。稳妥函数构造模式与寄生构造函数模式大致相同,但也有一些细微的区别。一是新创建对象的实例方法不引用this,二是不使用new操作符。

以上就是我们创建对象的七种模式,每种模式都有各自的优缺点,在具体使用时该如何选择,要具体情况具体分析。就先写到这里吧!

Javascript之对象的创建的更多相关文章

  1. JavaScript面向对象—对象的创建和操作

    JavaScript面向对象-对象的创建和操作 前言 虽然说在JavaScript编程语言中,函数是第一公民,但是JavaScript不仅支持函数式编程,也支持面向对象编程.JavaScript对象设 ...

  2. JavaScript(对象的创建模式)

    JavaScript和其他语言略有不同,在JavaScript中,引用数据类型都是对象(包括函数).不过,在JavaScript中并没有“类”的概念,这决定了在JavaScript中不能直接来定义“类 ...

  3. Javascript实现对象的创建

    能使用{}创建对象就不要使用new Object,能使用[]创建数组就不要使用new Array,JS中字面量的访问速度要高于对象. 1.通过object构造函数创建单个对象 var o = new ...

  4. JavaScript原生对象及扩展

    来源于 https://segmentfault.com/a/1190000002634958 内置对象与原生对象 内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始 ...

  5. 《JavaScript高级程序设计》读书笔记--(4)对象的创建

    ECMAScript支持面向对象(OO)编程,但不使用类或者接口.对象可以在代码执行过程中创建或增强,因此具有动态性而非严格定义的实体.在没有类的情况下,可以采用下列模式创建对象. 对象的创建 工厂模 ...

  6. JavaScript对象的创建之使用json格式定义

    json: javascript simple object notation. json就是js的对象,但是它省去了xml中的标签,而是通过{}来完成对象的说明. 定义对象 var person = ...

  7. javascript中对象的不同创建方法

    javascript中的对象与一般的面向对象的程序设计语言(c++,Java等)不同,甚至很少有人说它是面向对象的程序设计语言,因为它没有类.javaScript只有对象,不是类的实例.javascr ...

  8. javascript对象的创建--相对java 怎样去创建了"类"i以及实例化对象

    由于javascript没有java那么多基本类型,同时也没有提供class这个东西,那么我们想实现javascript的对象创建应该怎么办呢,我简单地从w3c提供的课件中提取了一下几种方法: 一.工 ...

  9. Javascript我学之五对象的创建与使用

    本文是金旭亮老师网易云课堂的课程笔记,记录下来,以供备忘. 对象的创建 JavaScript对象有两种类型   1).Native:在ECMAScript标准中定义和描述,包括JavaScript内置 ...

随机推荐

  1. (转)解决dubbox-demo-provider.xml报错的问题:提示Failed to read schema document

    背景:在eclipse项目中,经常会遇到xml文件提示找不到.xsd文件的情况.很有必要弄清xsd文件的加载过程! 1 解决过程 dubbo-demo-provider导入eclipse后dubbox ...

  2. Jenkins(三)---Jenkins初始配置和插件配置

    从Jenkins(二)中可以知道 jenkins 的工作目录为/opt/jenkins [很重要!!!][很重要!!!][很重要!!!]在配置此目录以前,将这两台的主机进行配置为ssh root用户无 ...

  3. 什么是Docker并且它为什么这么受欢迎

    什么是Docker (why it's so hot than hot) Docker是一个使用容器来方便快捷的创建,部署,运行程序的工具,容器允许开发人员将应用程序的一切打包(镜像),例如库和其他的 ...

  4. 【Asp.net入门08】第一个Asp.net应用程序-创建窗体并设置其样式

    本节内容: 添加一个aspx窗体并设计窗体内容 为aspx窗体添加样式 前面我们为PartyInvites应用程序项目添加了两个c#文件:GuestResponse.cs和ResponseReposi ...

  5. Cloudstack安装(二)

    Cloudstack安装 官方文档参考: http://docs.cloudstack.apache.org/projects/cloudstack-installation/en/4.9/qig.h ...

  6. P2054 [AHOI2005]洗牌

    P2054 [AHOI2005]洗牌 题目描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度 ...

  7. dp px 互转工具类

    public class DensityUtils { public static int dpToPx(Context context,int dp){ float density = contex ...

  8. WCF: Retry when service is in fault state.

    Service Host: using System; using System.Configuration; using System.ServiceModel; using System.Serv ...

  9. [php]mysqli操作流程

    <?php class SqlTools{ private $con; private $trans; public function __construct($host, $user, $ps ...

  10. 基本控件文档-UISegment属性

    CHENYILONG Blog 基本控件文档-UISegment属性 Fullscreen   UISegment属性技术博客http://www.cnblogs.com/ChenYilong/ 新浪 ...