JavaScript学习——面向对象(一)——创建对象(工厂模式和构造器模式)

面向对象

  JavaScript中的对象定义是:无序属性的集合,其属性值可以包含基本值,对象以及函数。

创建对象的方式:

1,使用工厂模式创建对象:

  使用工厂模式创建对象就是创建一个Object对象,再给对象添加属性和方法,工厂模式虽然解决了创建多个相同的对象创建的问题,但是不能识别对象的类型。

<!DOCTYPE html>
<html>
    <head>
        <meta  charset="UTF-8">
        <title>创建对象的几种方式-工厂模式</title>
        <script>
            function createPerson(name,age,job){
                var obj=new Object();
                obj.name=name;
                obj.age=age;
                obj.job=job;
                obj.sayName=function(){
                    alert("我的名字是"+this.name);
                }

                return obj;
            }

            var person1=createPerson("猪八戒",28,"医生");
            var person2=createPerson("孙悟空",18,"教师");
        </script>
    </head>
    <body>
        
    </body>
</html>

2,使用构造器模式创建对象

<!DOCTYPE html>
<html>
    <head>
        <meta  charset="UTF-8">
        <title>创建对象的几种方式-工厂模式</title>
        <script>
            function createPerson(name,age,job){
                var obj=new Object();
                obj.name=name;
                obj.age=age;
                obj.job=job;
                obj.sayName=function(){
                    alert("我的名字是"+this.name);
                }

                return obj;
            }

            var person1=createPerson("猪八戒",28,"医生");
            var person2=createPerson("孙悟空",18,"教师");
        </script>
    </head>
    <body>
        
    </body>
</html>

从代码可以看出,构造模式和工厂创建的对象的区别是:

  没有显示的创建对象

  直接将属性和方法赋值给了this对象

  没有return语句

创建构造函数的注意事项:构造函数的名称第一个字母应该大写,普通 的函数的名称都是小写,构造本身也是函数,也能够被调用。

使用构造函数创建一个对象必须要使用new操作符,使用new操作符调用构造函数经历的4个步骤:

  创建一个新对象

  将构造函数的作用域赋值给新对象(this指向了这个对象)

  执行构造函数中的代码(为对象添加属性和方法)

  返回一个新的对象

将构造函数当作普通函数来使用时候:

  在全局作用域中调用一个函数的时候,this指向Global对象(也就是window对象)在调用完后可以使用window对象来调用方法

 //将构造函数当作普通函数来使用的时候
 Person("沙和尚",38,"服务员");   //添加到window中去了
 window.sayName()

将构造函数放在另一个对象中使用的时候:

  使用call()方法在某个特定的对象的作用域中调用Person方法,是在o对象中调用的,所以o对象就拥有了所有的属性和方法

var o=new Object();
Person.call(o,"Kirs",25,"Nurse");
o.sayName();     //Kirs的职位是:Nurse

构造函数创建对象的问题:在每使用一次构造函数创建一个对象,都会为该对象创建对应的 属性和方法,每个属性和方法都是对象自己的,同种类型的不同对象的方法都不相同,但是他们所作的工作都是相同的。如下:对象person1的方法和person2的方法都是输出这个对象的name属性值,但是person2和person1的方法是不相等的,像这样每创建一个对象就创建一个函数没有必要。

<!DOCTYPE html>
<html>
    <head>
        <title>
            对象的方法
        </title>
        <script>
            function Person(name,age){
                this.name=name;
                this.age=age;
                this.sayName=function(){
                    alert("我是"+this.name);
                }
            };
            var person1=new Person("猪八戒",12);
            var person2=new Person("孙悟空",20);

            person1.sayName();
            person2.sayName();

            alert(person1.sayName==person2.sayName);   //输出false
        </script>
    </head>
</html>

我们可以把函数放在外面,而在里面将sayName属性的值指向外面的函数,如下:

<!DOCTYPE html>
<html>
    <head>
        <title>
            对象的方法定义
        </title>
        <script>

            function sayName(){
                alert(this.name);
            }

            function Person(name,age){
                this.name=name;
                this.age=age;
                //this.sayName=sayName();这个样是错误的,()是调用方法
                this.sayName=sayName;
            }

            var person1=new Person("猪八戒",29);
            var person2=new Person("孙悟空",20);

            person1.sayName();
            person2.sayName();

            alert(person2.sayName==person1.sayName);    //true
        </script>
    </head>
</html>

  这样,person1和person2就共享了全局作用域中的同一个函数,不用为每一个对象都创建一个方法,但是这样又会出现了新的问题:如果一个构造函数拥有多个方法,那么就需要为在全局作用域中创建多个方法,这样一来我们自定义的引用类型就没有封装性可言了。我们可以使用原型来解决这个问题。

o