# Encapsulation Of JavaScript Object

# 前言

今天看到阮一峰的一篇讲对象封装的文章,小有收获。在此借这篇博客记录一下,在这里,我将会以变出一支篮球队为例来展开文章

# 生成一个实例对象

生成一个最简单的对象的方法就是let player = {}。一个球员就这样诞生了,不过现在它还什么都不是,没有四肢,没有头脑,更不会打球。于是我要给他赋予这些东西,也就是属性。

let player1 = {
  name: "Curry",
  number: 30,
  team: "Warriors"
};
1
2
3
4
5

这样,我创建了一个名叫 Curry,球衣号码为 30 号,为勇士队效力的球员。不过篮球不是一个人的运动,Curry 还需要队友:

let player2 = {
  name: "Thompson",
  number: 11,
  team: "Warriors"
};

let player3 = {
  name: "Durant",
  number: 35,
  team: "Warriors"
};
1
2
3
4
5
6
7
8
9
10
11

唉,等等。要是每一个球员都像上面的方式来创造,只是写五个人的首发阵容还行,但 NBA 一支球队有 15 人,整个联盟 30 支球队,我要是这样一个一个写估计离猝死不远了。

# evolution1:使用函数

使用函数的优点就是可复用性高,只要声明定义了一次,就能随便调用了。

function Player(name, number) {
  return {
    name: name,
    number: number
  };
}
1
2
3
4
5
6

我们定义了一个 Player 的函数,用它来生成球员:

let player4 = Player("Green", 23);
let player5 = Player("Iguodala", 9);
1
2

# evolution2:构造函数

使用构造函数:

function Player(name, number) {
  this.name = name;
  this.number = number;
}

//继续创造球员
let player6 = new Player("livingston", 34);
1
2
3
4
5
6
7

# evolution3: 使用原型 Prototype

似乎上面那种方式已经足够好了,但我之前就已经埋下了一个坑:think about, 我在定义player1的时候还有一个team属性,通过构造函数来生成一个个实例的时候,team属性都会被生成一次,明明大家的team属性都一样,还要反复生成,这会浪费计算机的内存。于是乎,我们可以将众多实例共有的属性直接添加到其构造函数的 Prototype 里:

Player.prototype.team = "Warriors";

console.log(player4.team); //Warriors
1
2
3

# Ending

这样,一个球队就这样建立起来了。