面向对象(三):创建多个对象的方案

94 阅读2分钟

JavaScript 对象系列

面向对象(一):认识对象

面向对象(二):认识JavaScript中对象的原型

面向对象(三):创建多个对象的方案

面向对象(四):掌握原型链

面向对象(五):ES6 类的基本使用

面向对象(六):JavaScript中的7种继承方式

面向对象(七):ES6的class转ES5的源码阅读

第三篇

对象创建的方式,一般有两种:

  1. 字面量(常用)
  2. 构造函数

针对定义一个对象,随你采用哪种方式都是可以的。但是如果是下面这种情况呢?

 var p1 = {
   name: "james",
   age: 35,
   playing: function (team) {
     console.log(`${this.name}效力于${team}`);
   },
 };
 var p2 = {
   name: "curry",
   age: 30,
   playing: function (team) {
     console.log(`${this.name}效力于${team}`);
   },
 };
 ​
 var p3 = {
   name: "kobe",
   age: 40,
   playing: function (team) {
     console.log(`${this.name}效力于${team}`);
   },
 };

从上面,可以发现定义了三个对象,并且对象的结构一模一样,那么对于程序员来说,不进行抽离,天理难容。

工厂模式

  • 工厂模式其实是一种常见的设计模式;
  • 工厂模式有一个工厂方法,用于创建新的对象
 // 工厂方法
 function createPerson(name, age) {
   var p = new Object();
   p.name = name;
   p.age = age;
   p.playing = function (team) {
     console.log(`${this.name}效力于${team}`);
   };
   return p;
 }
 ​
 var p1 = createPerson("james", 35);
 var p2 = createPerson("curry", 30);
 var p3 = createPerson("kobe", 40);

优点:主要定义一个工厂方法,进行调用,就能创建多个对象;代码量少;

缺点:获取不到函数的真实类型(都是Object类型)

 console.log(p1) // { name: 'james', age: 35, playing: [Function (anonymous)] }

构造函数

  • 一个函数直接通过 () 调用,被称为普通函数;
  • 一个函数通过 new 调用,则被称为构造函数;
  • 约定俗成的规定,构造函数的首字母要大写,为了其他人便于区分;
 function Person(name, age) {
   this.name = name;
   this.age = age;
   this.playing = function (team) {
     console.log(`${this.name}效力于${team}`);
   };
 }
 ​
 var p1 = new Person("james", 35);
 var p2 = new Person("curry", 30);
 var p3 = new Person("kobe", 40);

优点:可以清楚的知道对象的类型

 console.log(p1) 
 // Person { name: 'james', age: 35, playing: [Function (anonymous)] }
 // Person 类型

缺点:就是浪费内存空间(针对于函数)

每调用一次构造函数,就会在堆内存空间里面开辟一个新的地址来保存 playing函数。如果创建对象,创建了100个,那么就会在内存空间中,创建出100个内存地址。但是呢?100个内存地址里面保存的信息基本上又是一样的,所以有点浪费性能。

构造函数 + 原型

上面,我们知道了构造函数,创建多个对象的缺点,就是浪费内存空间。所以可以利用原型,来优化一下,共享一个函数,只需要开辟一个空间。

函数都是具有函数的原型(prototype)

 function Person(name, age) {
   this.name = name;
   this.age = age;
 }
 // 共享方法绑定在原型上
 Person.prototype.playing = function (team) {
   console.log(`${this.name}效力于${team}`);
 };
 ​
 var p1 = new Person("james", 35);
 var p2 = new Person("curry", 30);
 var p3 = new Person("kobe", 40);
 ​
 console.log(p1);

这样就保存了构造函数的优点,又解决了构造函数的缺点。