一、工厂模式
工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程。
考虑到在 ECMAScript 中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节。
function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); }; return o; } var person1 = createPerson("Nicholas", 29, "Software Engineer"); var person2 = createPerson("Greg", 27, "Doctor"); console.log(person1); console.log(person2);
运行结果如下图所示:
函数 createPerson()能够根据接受的参数来构建一个包含所有必要信息的 Person 对象。
可以无数次地调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象。
工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。
二、构造函数模式
ECMAScript 中的构造函数可用来创建特定类型的对象,像 Object 和 Array 这样的原生构造函数,在运行时会自动出现在执行环境中。
此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
可以使用构造函数模式将前面的例子重写如下:
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); console.log(person1); console.log(person2);
运行结果如下图所示:
在这个例子中,Person()函数取代了 createPerson()函数。
我们注意到,Person()中的代码 除了与 createPerson()中相同的部分外,还存在以下不同之处:
1.没有显式地创建对象;
2.直接将属性和方法赋给了 this 对象;
3.没有 return 语句。
要创建 Person 的新实例,必须使用 new 操作符。以这种方式调用构造函数实际上会经历以下 4 个步骤:
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。
构造函数与其他函数的唯一区别,就在于调用它们的方式不同。
不过,构造函数毕竟也是函数,不存在定义构造函数的特殊语法。
任何函数,只要通过 new 操作符来调用,那它就可以作为构造函数。
而任何函数,如果不通过 new 操作符来调用,那它跟普通函数也不会有什么两样。
使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍。
三、原型模式
我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么 prototype 就是通过调用构造函数而创建的那个对象实例的原型对象。
使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true
在此,我们将 sayName()方法和所有属性直接添加到了 Person 的 prototype 属性中,构造函数变成了空函数。
即使如此,也仍然可以通过调用构造函数来创建新对象,而且新对象还会具有相同的属性和方法。
但与构造函数模式不同的是,新对象的这些属性和方法是由所有实例共享的。
换句话说, person1 和 person2 访问的都是同一组属性和同一个 sayName()函数。
缺点:原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。 但是实例一般都是要有属于自己的全部属性,实力属性不能共享。
原文:https://www.cnblogs.com/gg-qq/p/10669717.html