# 创建对象的方式
## 创建对象的方式1:使用Object构造器
```
var box = new Object()
box.name = 'lee'
```
存在的问题是:创建多个类似的对象,就需要重复实例化,写多次上面的重复代码
## 创建对象的方式2:工厂模式
```
funciton createObject (name, age) {
var obj = new Object()
obj.name = name
obj.age = age
obj.run = function () {
return this.name + this.age
}
return obj
}
var box1 = createObject('Lee', 100)
var box2 = createObject('Jack', 200)
alert(box1.run())
alert(box2.run())
```
工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根部无法搞清楚他们到底是哪个对象的实例
```
typeof box1 // object
typeof box2 // object
box1 instanceof Object // true
box2 instanceof Object // true
```
无论怎样,所产生的所有实例都是Object类型,无法区分每个实例到底是那个对象的实例
## 创建对象的方式3:构造函数(方法)
ECMAScript中可以词用构造函数(方法)可以用来创建特定的对象。类似于Object对象
```
function Box (username, age) {
this.username = username
this.age = age
this.run = function () {
return this.username + this.age
}
}
var box1 = new Box('Lee', 100)
var box2 = new Box('Jack', 200)
box1 instanceof Box // true,即通过Box产生的实例都是Box类型的
```
即解决了重复实例化的问题,又解决了对象识别的问题,但问题是,这里并没有new Object(),为什么可以实例化Box()?这个是哪里来的呢?
使用了构造函数的方法,和使用工厂模式的方法他们不同之处如下:
1. 构造函数方式没有显示的创建对象(new Object());
2. 直接将属性和方法赋值给this对象;
3. 没有return语句。
规范:
1. 函数名和实例化构造名相同且大写(PS:非强制,单这么写有助于区分构造函数和普通函数)
2. 通过构造函数创建对象,必须使用new 运算符
构造函数生产对象的过程如下:
1. 当使用了构造函数,并且new 构造函数(),那么后台就自动执行了 new Object();
2. 将构造函数的作用于给新对象,(即 new Object()创建出来的对象),而函数体内部的this就代表new Object()出来的对象;
3. 执行构造函数内部的代码;
4. 返回新对象(后台直接返回)。
使用对象冒充的方式进行调用:
```
var obj = new Object()
Box.call(obj, 'Lee', 100)
obj.run()
```
构造函数内部的方法是引用类型,相当于
```
this.run = new Function('return this.name + this.age')
```
这样一来每个实例都会有自己的一个run方法体占据内存空间,可以通过构造函数外面绑定一个函数的方法来保证引用地址的一致性,但这种做法没什么必要,并且因为run()是全局函数,所以外部也可以调用
```
function Box (username, age) {
this.username = username
this.age = age
this.run = run
}
function run () {
return this.username + this.age
}
run() // 外部恶意调用
```