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

    学习内容 标准文档流 流动模型(flow model) 浮动模型(float model) CSS基本布局 能力目标 理解标准文档流 使用流动模型实现页面布局 使用浮动模型实现页面布局 掌握常用CSS ...

  2. Android自定义 Dialog 对话框

    Android自定义Dialoghttp://www.cnblogs.com/and_he/archive/2011/09/16/2178716.html Android使用自定义AlertDialo ...

  3. linux内核增加系统调用--Beginner's guide

    Linux内核中设置了一组用于实现系统功能的子程序,称为系统调用.系统调用和普通库函数调用非常相似明知是系统调用由操作系统核心提供,运行于核心态,而普通的函数调用由函数库或用户自己提供,运行于用户态. ...

  4. echarts分组柱状图的前后台处理 带平均线显示

    原生的echarts使用: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /&g ...

  5. C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}

    C/C++:一个基类继承和多个基类继承的区别 1.对多个基类继承会出现类之间嵌套时出现的同名问题,如果同名变量或者函数出现不在同一层次,则底层派生隐藏外层比如继承基类的同名变量和函数,不会出现二义性, ...

  6. Docker集群管理Swarm数据持久化

    一.前言 和docker容器一样,Swarm集群中运行的服务也能够做数据持久化.我们可以通过volume.bind和nfs等方式来实现swarm集群应用数据的持久化.其实和docker数据持久化的形式 ...

  7. python基础之collections模块

    Counter Counter是一个简单的计数器,可以统计一段字符串中各个元素出现的次数: import collections counter_1=collections.Counter('kjsd ...

  8. Ansible9:条件语句

    目录 一.when 1.基本用法 2.在when中使用jinja2的语法 3.使用bool值作为when的判断条件 4.在when中使用defined关键字 5.when在循环语句中的使用方法 6.在 ...

  9. PyQt 5.4参考指南 ---- PyQt5和PyQt4之间的差异

    欢迎关注博主主页,学习python视频资源,还有大量免费python经典文章 sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/in ...

  10. java基础-Integer类常用方法介绍

    java基础-Integer类常用方法介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在实际程序使用中,程序界面上用户输入的数据都是以字符串类型进行存储的.而程序开发中,我们需 ...