查看: 762|回复: 0

[JavaScript/JQuery] 原生js的对象创建模式以及优缺点

发表于 2017-4-20 08:00:01
1.简单工厂模式
  1. //
  2. function createPerson(name, age, job ) {
  3. var o = new Object();
  4. o.name = name;
  5. o.age = age;
  6. o.job = job;
  7. o.sayName = function() {
  8. alert(this.name);
  9. }
  10. return o;
  11. }
  12. var person1 = createPerson("spademan", 26, "front-end");
  13. var person2 = createPerson("ivan", 27, "seller");
  14. person1.sayName(); //"spademan"
  15. person2.sayName(); //"ivan"
复制代码

特点: 通过 new Object() 来创建一个对象实例,并为其添加属性和方法并返回

优点: 工厂类集中了所有对象的创建,便于对象创建的统一管理,且可以大量创建

缺点:(1).工厂模式却无从识别对象的类型,因为它们直接由 Object() 构造函数创建,原型链上只有 Object.prototype 对象,不像Date、Array等 .
(2).每创建一个对象实例,就会为每个对象实例创建一遍相同功能但是是不同函数实例的方法,它们并不相等。这显然是不可取的
另外在相应的业务方面,除非是适用场景,否则不可滥用工厂模式,会造成代码的复杂度(参考)

注意:除了简单工厂模式之外还有抽象工厂模式

2.构造函数模式
  1. function GitHub(name, url) {
  2. this.name = name;
  3. this.url = url;
  4. this.alertUrl = function() {
  5. alert(this.url);
  6. }
  7. }
  8. var git = new GitHub('spademan', 'https://github.com/spademan');
  9. console.log(git instanceof GitHub); // true, 判断git是否是GitHub的实例,即解决了工厂模式中不能识别对象的类型的问题
复制代码

特点: 需要使用new,并且没有return关键字

优点: 可以识别对象的类型

缺点:使用构造函数的最大的问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的),然而创建两次完全相同的方法是没有必要的,因此,我们可以将函数移到对象外面(这一点和工厂模式相同)

3.原型模式
  1. function Person() {}
  2. Person.prototype.name = 'spademan'
  3. Person.prototype.age = 23
  4. Person.prototype.getName = function () {
  5. return this.name
  6. }
  7. Person.prototype.setName = function () {
  8. this.name = name
  9. }
  10. var spademan_1 = new Person()
  11. var spademan_2 = new Person()
  12. console.log(spademan_1.getName === spademan_2.getName) // => true
复制代码

特点: 构造函数内不定义属性和方法,把属性和方法都定义在构造函数的原型上。这样所有的对象实例都共享对象原型上的属相和方法

优点: 多个实例可以共享原型上的属性和方法

缺点: 修改原型上的一些引用属性,所有实例对应的属性也将被改变,这样可能带来一些问题

4.构造函数模式 + 原型模式(也叫混合模式)
  1. // 写法1
  2. function Person(name, age) {
  3. this.name = name
  4. this.age = age
  5. this.getAge = function () {
  6. return this.age
  7. }
  8. }
  9. Person.prototype.country = 'China'
  10. Person.prototype.getName = function () {
  11. return this.name
  12. }
  13. Person.prototype.setName = function (name) {
  14. this.name = name
  15. }
  16. var spademan = new Person('spademan', 26)
  17. var spademan_2 = new Person('spdeman_2', 27)
复制代码
  1. //写法2
  2. function Person(name, age) {
  3. this.name = name
  4. this.age = age
  5. this.getAge = function () {
  6. return this.age
  7. }
  8. }
  9. Person.prototype.country = 'China'
  10. Person.prototype.getName = function () {
  11. return this.name
  12. }
  13. Person.prototype.setName = function (name) {
  14. this.name = name
  15. }
  16. var spademan = new Person('spademan', 26)
  17. var spademan_2 = new Person('spdeman_2', 27)
复制代码

优点: 构造函数内定义私有的属性和方法,构造函数的原型上定义共有的属性和方法。是目前最常用的方式之一

5.模块模式(参考)
  1. // 写法1
  2. var MODULE = (function () {
  3. var my = {},
  4. privateVariable = 1;
  5. function privateMethod() {
  6. // ...
  7. }
  8. my.moduleProperty = 1;
  9. my.moduleMethod = function () {
  10. // ...
  11. };
  12. return my;
  13. }());
复制代码
  1. // 写法2
  2. var MODULE = (function (my) {
  3. var privateVariable = 1;
  4. function privateMethod() {
  5. // ...
  6. }
  7. my.moduleProperty = 1;
  8. my.moduleMethod = function () {
  9. // ...
  10. };
  11. return my;
  12. }(MODULE|| {}));
复制代码


回复

使用道具 举报