


## 创建对象的几种方式

### 通过Object

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>01_Object构造函数模式</title>
</head>
<body>
<!--
方式一: Object构造函数模式
  * 套路: 先创建空Object对象, 再动态添加属性/方法
  * 适用场景: 起始时不确定对象内部数据
  * 问题: 语句太多
-->
<script type="text/javascript">
    /*
    一个人: name:"Tom", age: 12
     */
    // 先创建空Object对象
    var p = new Object()
    p = {} //此时内部数据是不确定的
    // 再动态添加属性/方法
    p.name = 'Tom'
    p.age = 12
    p.setName = function (name) {
        this.name = name
    }

    //测试
    console.log(p.name, p.age)
    p.setName('Bob')
    console.log(p.name, p.age)


</script>
</body>
</html>

```


### 方式二：对象字面量

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>02_对象字面量</title>
</head>
<body>
<!--
方式二: 对象字面量模式
  * 套路: 使用{}创建对象, 同时指定属性/方法
  * 适用场景: 起始时对象内部数据是确定的
  * 问题: 如果创建多个对象, 有重复代码
-->
<script type="text/javascript">
    var p = {
        name: 'Tom',
        age: 12,
        setName: function (name) {
            this.name = name
        }
    }

    //测试
    console.log(p.name, p.age)
    p.setName('JACK')
    console.log(p.name, p.age)

    var p2 = {  //如果创建多个对象代码很重复
        name: 'Bob',
        age: 13,
        setName: function (name) {
            this.name = name
        }
    }

</script>
</body>
</html>
```



### 方式三：工厂模式

- 方式：通过工厂函数动态创建对象并返回。

返回一个对象的函数，就是**工厂函数**。

- 适用场景: 需要创建多个对象。

- 问题: 对象没有一个具体的类型，都是Object类型。

由于这个问题的存在，工厂模式用得不多。

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>03_工厂模式</title>
</head>
<body>
<!--
方式三: 工厂模式
  * 套路: 通过工厂函数动态创建对象并返回
  * 适用场景: 需要创建多个对象
  * 问题: 对象没有一个具体的类型, 都是Object类型
-->
<script type="text/javascript">
    function createPerson(name, age) { //返回一个对象的函数===>工厂函数
        var obj = {
            name: name,
            age: age,
            setName: function (name) {
                this.name = name
            }
        }

        return obj
    }

    // 创建2个人
    var p1 = createPerson('Tom', 12)
    var p2 = createPerson('Bob', 13)

    // p1/p2是Object类型

    function createStudent(name, price) {
        var obj = {
            name: name,
            price: price
        }
        return obj
    }

    var s = createStudent('张三', 12000)
    // s也是Object


</script>
</body>
</html>

```



### 方式四：自定义构造函数

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>04_自定义构造函数模式</title>
</head>

<body>
<!--
方式四: 自定义构造函数模式
  * 套路: 自定义构造函数, 通过new创建对象
  * 适用场景: 需要创建多个类型确定的对象
  * 问题: 每个对象都有相同的数据, 浪费内存
-->
<script type="text/javascript">
    //定义类型
    function Person(name, age) {
        this.name = name
        this.age = age
        this.setName = function (name) {
            this.name = name
        }
    }

    var p1 = new Person('Tom', 12)
    p1.setName('Jack')
    console.log(p1.name, p1.age)
    console.log(p1 instanceof Person)

    function Student(name, price) {
        this.name = name
        this.price = price
    }

    var s = new Student('Bob', 13000)
    console.log(s instanceof Student)

    var p2 = new Person('JACK', 23)
    console.log(p1, p2)


</script>
</body>
</html>

```


方式四引入了继承。

## 继承的几种方式


### 通过构造函数继承

在子类型构造函数中通用call()调用父类型构造函数


### 原型链继承

子类型的原型为父类型的一个实例对象



### 组合继承



