Javascript 构造函数模式、原型模式

前两天写完组合继承,打算总结一下原型继承的,不过今天看了一下工厂模式、构造函数模式和原型模式,觉得有必要总结一下以加深印象。

——————————————————————————————————————————————————————————————————————————————————碎碎念。

1.工厂模式

《Javascript 高级程序设计(第3版)》 用了寥寥十多行介绍了工厂模式。我找了一些相关资料,想确定一下这种模式的具体适用场景和优势。按照资料中的说法,是考虑到 ECMAScript 无法创建类,所以:

创建一个对象,紧接着描述对象的属性和方法,最后用另一个对象把它们封装起来当作接口。

按照上面描述的,工厂函数是用来在 Javascript 中实现类似于 Java 中类的功能。通过调用工厂函数,可以创建多个相似的对象实例。

简单工厂模式:使用一个类(通常为单体)来生成实例。
    复杂工厂模式:使用子类来决定一个成员变量应该是哪个具体的类的实例。

关于 Javascript 使用工厂模式的优点,根据网上的总结,大概有以下几点:

a. 消除对象之间的耦合(这个不太明白,消除谁与谁的耦合?);

b. 在进行批次相关设置时,把所有实例化的代码都集中在一个位置,有助于创建模块化的代码,减少代码量;

c.  用于许多小型对象组成一个大对象。

缺点:

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

.....这个模式先留着吧,没太搞透彻优势在哪。以后领悟了的话再来补充。引用《Javascript 设计模式与开发实践》P5中的一段话:

“而在 Javascript 这种类型模糊的语言中,对象多态性是天生的,一个变量既可以指向一个类,又可以随时指向另外一个类。Javascript 不存在类型耦合问题,自然也没有必要刻意把对象“延迟”到子类创建,也就是说,Javascript 实际上是不需要工厂方法模式的。 模式的存在首先是能为我们解决什么问题,这种牵强的模拟只会让人觉得设计模式既难懂又没什么用。”

2. 构造函数模式

关于封装: 在 Javascript 中,可以将一些属性和方法封装到构造函数内;

关于多态:在 Javascript 中不存在重载的概念,但可以通过参数个数和类型判断来模拟重载,但是 Javascript 中多态是与生俱来的。一个最简单的栗子:

同一个构造函数实例化得到的两个对象实例,可以给它们传入不同的参数,这两个对象实例是不同的。这就是面向对象编程的多态。

利用构造函数模式,可以创建多个实例,这些实例都被标定为了特定的类型。构造函数模式相比于工厂模式更为简单且易于实现,但也存在缺点:

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.arr = [];
    this.sayName = function(){
        alert(this.name);
    };
}
var person1 = new Person("Nicholas",29,"Software Engineer");
var person2 = new Person("Greg",27,"Doctor");

console.log(person1.sayName==person2.sayName);//false
person1.arr.push(1);
console.log(person1.arr);//1

person2.arr.push(2);
console.log(person2.arr);//2

利用构造函数每实例化一个实例对象,构造函数内的方法都要在实例上重新创建一次。通过 person1.sayName==person2.sayName 返回的返回结果可以看到两个实例引用的方法是不同的。

注意:这一点也适用于数组。

可以通过将构造函数的方法放在外部,使得对象实例每次都引用同一个方法。

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

function sayName(){
        alert(this.name);
}

var person1 = new Person("Nicholas",29,"Software Engineer");
var person2 = new Person("Greg",27,"Doctor");

console.log(person1.sayName==person2.sayName);//true

通过将构造函数的方法提到外部作为:特权方法。可以使实例获得相同的方法引用。

但是这种方法也存在一些问题:将方法提到外部作为特权方法使得封装性变差。如果构造函数内部有很多个方法,这样做后果更为明显。

另外再看一个问题:如果构造函数内有多个固定属性,并且存在多个方法。实例化的时候要为每个对象都复制相同的固定属性,如果将方法放在构造函数内部,这些方法也要复制,即使都作为特权函数,也存在弊端。

总结,构造函数模式存在两点不足:1. 浪费内存;2. 可能会使封装性变差。

3.原型模式

原型模式的出现,解决了构造函数实例化过程中对固定属性个方法重复深复制的问题。

对于相同的属性和方法,只要在构造函数的原型对象上申明一次,构造函数的实例就可以共享同一个属性和方法。

function Person(){

}

Person.prototype.name = "Nicholas";
Person.prototype.sayName = function(){
    console.log(this.name);
}

var person1 = new Person();
var person2 = new Person();

console.log(person1.sayName===person2.sayName);//true
console.log(person1.name===person2.name);//true

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

但是可以看到,虽然原型模式能够解决固定属性和方法多次复制的问题,如果属性要根据不同实例对象改变,这时候最好还是把会随实例对象改变的属性放置在构造函数内部,这又用到了构造函数模式。将构造函数模式和原型模式相结合,就能利用这两个模式的优势。

function Person(name,age){
    //会随实例对象改变的属性
    this.name = name;
    this.age = age;
}
//不变的属性或者是方法
Person.prototype.job = "Soft Engineer";
Person.prototype.sayName = function(){
    console.log(this.name);
}

var person1 = new Person("Nicholas",28);
var person2 = new Person("Shelby",25);
时间: 2025-01-05 04:09:26

Javascript 构造函数模式、原型模式的相关文章

浅谈JavaScript中的原型模式

在JavaScript中创建对象由很多种方式,如工厂模式.构造函数模式.原型模式等: <pre name="code" class="html">//工厂模式 function createPerson(name,age,job) { var o = new Object; o.name = name; o.age = age; o.job = job; o.sayName = function() { alert(this.name); } retur

基于上一篇的模块化思路,巩固个小知识点——构造函数与原型模式

具体可参考红皮书第三版中的6.2.4章 书中的例题详细讲解了什么是原型模式 function fop(){}; fop.prototype.name="xiaohong"; fop.prototype.age="12"; fop.prototype.sayName=function(){ console.log(this.name); } var per1=new fop(); per1.sayName(); var per2=new fop(); per2.say

深入javascript——构造函数和原型对象

深入javascript——构造函数和原型对象 常用的几种对象创建模式 使用new关键字创建 最基础的对象创建方式,无非就是和其他多数语言一样说的一样:没对象,你new一个呀! var gf = new Object(); gf.name = "tangwei"; gf.bar = "c++"; gf.sayWhat = function() { console.log(this.name + "said:love you forever");

链接:深入理解javascript构造函数和原型对象

链接:深入理解javascript构造函数和原型对象http://www.jb51.net/article/55539.htm

理解javascript中的原型模式

一.为什么要用原型模式. 早期采用工厂模式或构造函数模式的缺点:  1.工厂模式:函数creatPerson根据接受的参数来构建一个包含所有必要信息的person对象,这个函数可以被无数次的调用,工厂模式尽管解决了创建多个相似对象的问题,却没有解决对象识别的问题(返回的是自定义的一个对象o,不明确对象o的类型).  2. 构造函数模式:构造函数的调用和其他oo语言一样,用new操作符来构建一个Person的实例:javascript中的构造函数也是函数(所以也可以直接像普通函数那样直接调用方法名

JavaScript 面向对象 (prototype 原型模式)

一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力.比如,如果网页上有一栏"用户名"要求填写,浏览器就无法判断访问者是否真的填写了,只有让服务器端判断.如果没有填写,服务器端就返回错误,要求用户重新填写,这太浪费时间和服务器资源了. 因此,网景公司急需一种网页脚本语言,使得浏览器可以与网页互动.工程师_Brend

JavaScript设计模式-3.原型模式

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>js高级语法3-原型模式 </title> 6 </head> 7 <body> 8 <script> 9 /* 10 javascript原型模式(prototype): 11 1. 原型是一个对象,其他对象可以通过它实现属性的继承,所有的

javascript--面向对象(二、工厂模式,构造函数,原型模式)

一.前言 上一篇介绍了对象的基本简单的概念和对象的数据属性和访问器属性,以及对这两种属性类型的一些操作,接来说一下与创建对象的模式. 二.创建对象的方式 (1)工厂模式 这种模式就是通过创建一个Object对象,并将属性和方法保存在Object对象中,将Object对象返回. function createPerson(name, age, job){ var obj = new Object();//通过创建Object来保存传递进来的属性 obj.name = name; obj.age =

谈谈对Javascript构造函数和原型对象的理解

对象,是javascript中非常重要的一个梗,是否能透彻的理解它直接关系到你对整个javascript体系的基础理解,说白了,javascript就是一群对象在搅..(哔!). 常用的几种对象创建模式 使用new关键字创建最基础的对象创建方式,无非就是和其他多数语言一样说的一样:没对象,你new一个呀! var gf = new Object(); gf.name = "tangwei"; gf.bar = "c++"; gf.sayWhat = function

javascript构造函数及原型对象

/** @ javascript中没有类的概念,所以基在对象创建方面与面向对象语言有所不同* @ 对象创建的常用方法及各自的局限性* @ 使用Object或对象字面量创建对象* @ 工厂模式创建对象* @ 构造函数模式创建对象* @ 原型模式创建对象* @ 构造与原型混合模式创建对象*/ 使用Object或对象字面量创建对象 /* * @ 使用Object或对象字面量创建对象 * @ 最基本的创建对象的方法 */ // 创建一个student对象, new一个Object var student