一、工厂模式

1. 代码示例

function person(name, age) {
var p = new object();
p.name = name;
p.age = age;
p.sayName = function() {
console.log(this.name);
};
return p;
} var person1 = person('Bonnie', 26);
var person2 = person('Summer', 24);

2. 优点

解决了创建多个相似对象的问题。

3. 缺点

没有解决对象识别的问题。

二、 构造函数模式

1. 代码示例

function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
}
} var person1 = new Person('Bonnie', 26);
var person2 = new Person('Summer', 24);

牢记:构造函数在不返回值的情况下,默认会返回新对象的实例(构造函数模式)。 如果在构造函数内部末尾添加一个return语句,可以重写调用构造函数时返回的值(寄生构造函数模式)。

2.优点

创建自定义的构造函数意味着可以将它的示例标志为一种特定的类型(执行person1 instanceof Person为true)。这就是它比工厂模式更胜一筹的地方。

3.缺点

每个方法都要在每个实例上创建一遍。也就是说,使用构造函数模式创建的每个实例都包含着各自独有的同名函数。然而,创建两个完成同样任务的同名函数并没有必要。

可以像这样使构造函数创建的每个实例都引用一个方法:

function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = sayName;
}
function sayName() {
console.log(this.name);
}

但是这样带来的问题是被构造函数的不同实例共同引用的这个方法存在于全局作用域中,这一方面破坏了全局作用域,另一方面也破坏了该自定义类型的封装性。

三、 原型模式

1. 代码示例

function Person() {
} Person.prototype.name = "Bonnie";
Person.prototype.age = 26;
Person.prototype.sayName = function() {
console.log(this.name)
} var person1 = new Person();
var person2 = new Person();

2. 优点

可以让所有对象实例共享它所包含的属性和方法。

3. 缺点

首先,它省略了为构造函数传递初始化参数这一环节,这样所有实例默认都会取得相同的属性值。

更严重的是,其共享的本质对于引用类型的属性值(如数组)是非常不适合的:对于修改一个实例上引用类型的属性值也会修改另一个实例上的这个属性值。不过,其共享本质对于函数非常合适,因为方法本来就是共用的。而其对于基本值的属性也比较合适,因为可以通过在实例上添加同名的属性名来覆盖原型中的属性。

详见我的另一篇博客《原型与原型链》 的"一、创建对象的重要模式:原型模式"。

四、 组合使用构造函数模式和原型模式

1.代码示例

function Person(name, age) {
this.name = name;
this.age = age;
this.friends = ['Spring', 'Huiyun'];
}
Person.prototype.sayName = function() {
console.log(this.name);
} var person1 = person('Bonnie', 26);
var person2 = person('Summer', 24);

2. 优点

实例属性都在构造函数中实现,共享的属性和方法在原型中定义,是使用最广、认同度最高的一种创建自定义类型的方式。也是默认方式。

五、动态原型模式

1. 代码示例

function Person(name, age) {
this.name = name;
this.age = age; if (typeof this.sayName != 'function') {
Person.prototype.sayName = function() {
console.log(this.name);
}
}
}

2. 优点

只有在某方法不存在的情况下,才将该方法添加到原型上。添加到原型上这段代码只会在初次调用构造函数时才会执行。对原型所做的修改会立刻反映到所有实例中。

注意:不能使用对象字面量重写原型,因为如果已经创建了实例,那么重写原型会切断现有实例和新原型之间的联系。

六、寄生构造函数模式

1. 代码示例

function Person(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function() {
console.log(this.sayName);
}
return o;
}
var person1 = new Person('Bonnie', 26);

除了使用new操作符并把包装的函数叫做构造函数之外,该模式跟工厂模式是一模一样的。构造函数在不返回值的情况下默认返回新对象实例。而通过在构造函数内部末尾添加return语句,可以重写调用构造函数时返回的值。

2. 优点

该模式适于为特殊对象(如Array)创建具有新属性、新方法的实例。也就是说适于在某些已有的特殊类型(如Array)的基础上创建新的特殊类型(如SpecialArray)。

例如可以在Array的基础上,创建具有额外方法的数组:

function SpecialArray() {
var o = new Array();
o.push.apply(o, arguments);
o.getPipedStr = function() {
return this.join('|');
}
return o;
} var colors = new SpecialArray('red', 'blue', 'green');
console.log(colors);// ["red", "blue", "green", getPipedStr: ƒ]
console.log(colors.getPipedStr);//"red|blue|green"

3. 缺点

该模式返回的对象与构造函数以及构造函数的原型之间毫无关系。也就是说,该模式返回的对象与在构造函数外部超级多对象没什么不同。所以构造函数所表示的类型并不是实例的类型。

以上例来说:

colors instanceof SpecialArray;// false

七、 稳妥构造函数模式

1. 代码示例

function Person(name, age) {
var o = new Object();
//私有变量
var job = 'developer'; o.sayName = function() {
console.log(name);
}
o.sayJob = function() {
console.log(job);
}
return o;
}
var person1 = new Person('Bonnie', 26);
person.sayName()//'Bonnie'
person.sayJob()//'Job'

该方式创建的对象,除了sayName、sayJob方法以外,没有别的办法访问变量name、job。

2. 优点

该模式提供了固定的方法来访问构造函数中的原始数据(构造函数参数、私有变量)。除提供的方法外,没有其他办法可以访问其构造函数中的原始数据。这种安全性使得稳妥构造函数模式非常适合在某些安全执行环境(如ADsafe、Caja)下使用。

参考资料

《JavaScirpt高级程序设计》6.2

JavaScript创建对象的几种重要模式的更多相关文章

  1. JavaScript创建对象(三)——原型模式

    在JavaScript创建对象(二)——构造函数模式中提到,构造函数模式存在相同功能的函数定义多次的问题.本篇文章就来讨论一下该问题的解决方案——原型模式. 首先我们来看下什么是原型.我们在创建一个函 ...

  2. JavaScript 创建对象的七种方式

    转自:xxxgitone.github.io/2017/06/10/JavaScript创建对象的七种方式/ JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以 ...

  3. JavaScript创建对象的几种 方式

    //JavaScript创建对象的七种方式 //https://xxxgitone.github.io/2017/06/10/JavaScript%E5%88%9B%E5%BB%BA%E5%AF%B9 ...

  4. Javascript 创建对象的三种方法及比较【转载+整理】

    https://developer.mozilla.org/zh-CN/docs/JavaScript/Guide/Inheritance_and_the_prototype_chain 本文内容 引 ...

  5. javascript创建对象的方法--动态原型模式

    javascript创建对象的方法--动态原型模式 一.总结 1.作用:解决组合模式的属性和函数分离问题  2.思路:基本思路和组合模式相同:共用的函数和属性用原型方式,非共用的的函数和属性用构造函数 ...

  6. javascript 创建对象的7种模式

    使用字面量方式创建一个 student 对象: var student = function (){ name : "redjoy", age : 21, sex: women, ...

  7. javascript创建对象的几种方式

    javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON:但写法有很多种,也能混合使用.主要为下面几种:1.对象字面量的方式 person={firstname ...

  8. JavaScript创建对象的几种方式总结

    ECMA把对象定义为:无序属性的集合,其属性可以包含基本值.对象或者函数. 1. 使用Object构造函数创建对象 创建自定义对象的最简单的方式就是创建一个Object的实例,然后再为它添加属性和方法 ...

  9. JavaScript创建对象的6种方式

    JavaScript创建对象简单的说,无非就是使用内置对象(Object)或各种自定义对象,当然还可以用JSON,但写法有很多种,也能混合使用. 1.对象字面量的方式 person = {name : ...

随机推荐

  1. Qt浅谈之二十六图片滑动效果

    一.简介 博客中发现有作者写的仿360的代码,觉得其中图片滑动的效果很有意思,特提取其中的代码.并加上类似mac的画面移动的动画效果. 二.详解 1.代码一:界面滑动(QWidget) (1)slid ...

  2. rem布局原理

    昨天去面试,面试官竟然说他们用媒体查询针对不同的屏幕宽度做了9个不同的rem布局,呵呵... eg: html{font-size:20px;} div{width:16rem;height:100p ...

  3. Objective-C与Swift的混合编程

    Swift 被设计用来无缝兼容 Cocoa 和 Objective-C .在 Swift 中,你可以使用 Objective-C 的 API(包括系统框架和你自定义的代码),你也可以在 Objecti ...

  4. RHCE学习笔记 管理1 (第六章 第七章)

    第六章 利用linux 文件系统权限文件访问 1.linux文件系统权限 文件的权限分为:  rwx  读/写/执行 ls -l  /home   查看/home下文件 ls -ld /home   ...

  5. Java 通过JDBC连接Mysql数据库的方法和实例【图文说明】

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口 ...

  6. 在openrc中从keystone V2 到 V3

    #!/bin/bash ] then echo "Usage $0 <keystone.rc>" exit fi . $ NEW_OS_AUTH_URL=`echo $ ...

  7. Hibernate中使用Spring Data JPA

    一.配置文件的方式 1.pom.xml中引入相关依赖 <properties> <project.build.sourceEncoding>UTF-8</project. ...

  8. Codeforces 869C The Intriguing Obsession:组合数 or dp

    题目链接:http://codeforces.com/problemset/problem/869/C 题意: 红色.蓝色.紫色的小岛分别有a,b,c个. 你可以在两个不同的岛之间架桥,桥的长度为1. ...

  9. hadoop-0.20.1+120 hive-0.3.99.1+0 试用hwi(hive web interface

    摘自:http://www.chinacloud.cn/show.aspx?id=3274&cid=12 [日期:2010-07-04] 来源:淘宝数据平台团队  作者: [字体:大 中 小] ...

  10. IE跨Iframe时Session丢失问题

    例如IIS下,可以打开IIS窗口——〉选择一个网站——〉属性——〉http头,增加一个http头 然后输入头名:P3P 输入头内容:CP=CAO PSA OUR 点评:与上一个方法类似,此方法也要求第 ...