面向对象语言有一个非常显著的标志,那就是它们都有类的概念,通过类之间的继承就可以达到任意创建具有相同属性方法的对象。而在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. java回文算法

    1987891这个就是回文,判断“1987891”是不是回文? 1 public static boolean isPalindrome(String str) { return str.equals ...

  2. mac 必备工具

    iTerm 可以在一个窗口中垂直.水平分割窗口,而不用切换来切换去 一些基本功能如下: 1.分窗口操作:shift+command+d(横向)command+d(竖向) 2.查找和粘贴:command ...

  3. Kubernetes Pod 健康检查

    参考文档: https://jimmysong.io/kubernetes-handbook/guide/configure-liveness-readiness-probes.html 一.Pod的 ...

  4. Ubuntu 18.04设置dns

    最近使用了最新版的ubuntu 18.04运行一些服务,然后发现服务器经常出现网络不通的情况,主要是一些域名无法解析. 检查/etc/resolv.conf,发现之前修改的nameserver总是会被 ...

  5. GO_09:GO语言基础之reflect反射

    反射reflection 1. 反射可以大大的提高程序的灵活性,使得 interface{} 有更大的发挥余地 2. 反射使用 TypeOf 和 ValueOf 函数从接口中获取目标对象信息 3. 反 ...

  6. 朝韩危机-Python模拟导弹互射

    萨德系统是麻省理工学院的林肯实验室牵头开发的.林肯实验室可以说是美军方手中的一张王牌.二个反导系统(末段高空区域导弹防御(THAAD)系统,和 国家导弹防御系统(NMD))均由实验室牵头.它既是技术支 ...

  7. addEventListener() 事件监听

    addEventListener() 用于向指定元素添加事件. 可以向一个元素添加多次事件或者多次不同事件,后面的事件是不会覆盖前面的. 语法: element.addEventListener(ev ...

  8. numpy计算路线距离

    numpy计算路线距离 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 enumerate遍历数组 np.diff函数 numpy适用数组作为索引 标记路线上的点 \[X={X1,X ...

  9. 视音频数据处理入门:PCM音频采样数据处理

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  10. Linux初学之vmware Workstation 网络连接三种模式

    简介: VM(VMware Workstation简称VM,后面都将用VM代替阐述)是一款功能强大的虚拟化软件.VM支持在 单一的桌面上同时运行多款不同的操作系统,能够模拟完整的网络环境,支持pxe功 ...