面向对象语言有一个非常显著的标志,那就是它们都有类的概念,通过类之间的继承就可以达到任意创建具有相同属性方法的对象。而在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. 单点登录(二)----实战------简单搭建CAS---测试认证方式搭建CAS

    我们在上一篇文章中已经介绍了cas以及它的工作流程. 单点登录(一)-----理论-----单点登录SSO的介绍和CAS+选型 本章我们开始动手搭建一个完整的cas服务实现2个web之间的单点登录. ...

  2. HDU 5306 线段树

    吉司机课件题. 区间min,区间最值,区间和. 如果用最大值和次大值能更新区间和那就更新打标记,否则暴力dfs. #include<iostream> #include<cstdio ...

  3. 一次DS总结+一些闲话

    “只要你们搞懂这一轮……你们就可以……” 在zcy(或是xgg)来之前,hfu如是说. 但是…… “这一轮……可能是有一点……毕竟弄完了可以进……恩,我们的路还长啊!” 着实,也是.本人在xgg_na ...

  4. Fibonacci数列时间复杂度之美妙

    Fibonacci数列: fib(0)=1 fib(1)=1 fib(n)=fib(n-1)+fib(n-2) 上课老师出了一道题,求下列函数的时间复杂度: int fib(int d) { ) ; ...

  5. WARNING: pgstat wait timeout

      在ELK的邮件报警中,发现了一个 WARNING: pgstat wait timeout 的报错信息,看字面意思是pgstat有关操作等待超时.   通过google查询,发现在pg的邮件列表中 ...

  6. Windows下CVSNT安装配置

    首先要说明:X64下安装此软件会报 “cvs [login aborted]: WIN-4H9CRJO1TRA\Administrator: Switch to user failed due to  ...

  7. mac、linux 查看端口占用程序

    lsof -i:80 列出占用 80 端口的程序 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysqld 672 ruby 42u IPv4 ...

  8. 修改const保护的值

    先看代码: #include <stdio.h> void main() { const int num = 10; int *a = (int *)(void *)&num; / ...

  9. GO_02:GO语言开篇

    Go的发展史 Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后 ...

  10. Spark记录-Scala基础语法

    如果您熟悉Java语言语法和编程,那么学习Scala将会很容易.Scala和Java之间最大的句法差异在于行结束字符的分号(;) 是可选的. 当编写Scala程序时,它可以被定义为通过调用彼此的方法进 ...