• JavaScript学习12 JS中定义对象的几种方式


     

    JavaScript学习12 JS中定义对象的几种方式

      JavaScript中没有类的概念,只有对象。

      在JavaScript中定义对象可以采用以下几种方式:

      1.基于已有对象扩充其属性和方法

      2.工厂方式

      3.构造函数方式

      4.原型(“prototype”)方式

      5.动态原型方式

    一.基于已有对象扩充其属性和方法

    <script type="text/javascript">
    var object = new Object();
    object.name = "zhangsan";
    object.sayName = function(name)
    {
           this.name = name;
           alert(this.name);
    }
    object.sayName("lisi");
    </script>

      这种方式的弊端:这种对象的可复用性不强,如果需要使用多个对象,还需要重新扩展其属性和方法。

    二.工厂方式

    function createObject()
    {
           var object = new Object();
           object.username = "zhangsan";
           object.password = "123";
    
           object.get = function()
           {
                  alert(this.username + ", " + this.password);
           }
           return object;
    }
    
    var object1 = createObject();
    var object2 = createObject();
    
    object1.get();

    改进一:采用带参数的构造方法:

    function createObject(username, password)
    {
           var object = new Object();
    
           object.username = username;
           object.password = password;
    
           object.get = function()
           {
                  alert(this.username + ", " + this.password);
           }
    
           return object;
    }
    
    var object1 = createObject("zhangsan", "123");
    
    object1.get();

    改进二:让多个对象共享函数对象

      这样,不用每个对象都生成一个函数对象。

    function get()
    {
           alert(this.username + ", " + this.password);
    }
    
    //函数对象只有一份
    function createObject(username, password)
    {
           var object = new Object();
    
           object.username = username;
           object.password = password;
    
           object.get = get; //每一个对象的函数对象都指向同一个函数对象
    
           return object;
    }
    
    var object = createObject("zhangsan", "123");
    var object2 = createObject("lisi", "456");
    
    object.get();
    object2.get();

      优点:让一个函数对象被多个对象所共享,而不是每一个对象拥有一个函数对象。

      缺点:对象和它的方法定义分开了,可能会造成误解和误用。

    三.构造函数方式

      构造函数的定义方法其实和普通的自定义函数相同。

    function Person()
    {
           //在执行第一行代码前,js引擎会为我们生成一个对象
           this.username = "zhangsan";
           this.password = "123";
    
           this.getInfo = function()
           {
                  alert(this.username + ", " + this.password);
           } 
    
           //此处有一个隐藏的return语句,用于将之前生成的对象返回
           //只有在后面用new的情况下,才会出现注释所述的这两点情况
    
    }
    
    //生成对象
    var person = new Person();//用了new
    person.getInfo(); 

      改进版:加上参数:

    function Person(username, password)
    {
           this.username = username;
           this.password = password;
    
           this.getInfo = function()
           {
                  alert(this.username + ", " + this.password);
           }
    }
    
    var person = new Person("zhangsan", "123");
    person.getInfo();

    四.原型(“prototype”)方式

      例子:

    function Person()
    {
    }
    
    Person.prototype.username = "zhangsan";
    Person.prototype.password = "123";
    
    Person.prototype.getInfo = function()
    {
           alert(this.username + ", " + this.password);
    }
    
    var person = new Person();
    var person2 = new Person();
    
    person.username = "lisi";
    
    person.getInfo();
    person2.getInfo();

      使用原型存在的缺点:

      1.不能传参数;

      2.有可能会导致程序错误。

     

      如果使用原型方式来定义对象,那么生成的所有对象会共享原型中的属性,这样一个对象改变了该属性也会反映到其他对象当中。

      单纯使用原型方式定义对象无法在构造函数中为属性赋初值,只能在对象生成后再去改变属性值。

      比如,username改为数组后:

    function Person()
    {
    }
    
    Person.prototype.username = new Array();
    Person.prototype.password = "123";
    
    Person.prototype.getInfo = function()
    {
           alert(this.username + ", " + this.password);
    }
    
    var person = new Person();
    var person2 = new Person();
    
    person.username.push("zhangsan");
    person.username.push("lisi");
    person.password = "456";
    
    person.getInfo(); //输出:zhangsan,lisi, 456
    person2.getInfo(); //输出:zhangsan,lisi, 123
    
    //虽然没有对person2对象进行修改,但是它的name和person是一样的,即为zhangsan,lisi

     

      这是因为使用原型方式,person和person2指向的是同一个原型,即对应了同样的属性对象。

      对于引用类型(比如数组),两个对象指向了同一个引用,所以对一个所做的更改会影响另一个。

      而对于字符串(字面常量值),重新赋值之后就指向了另一个引用,所以二者的修改互不影响。

     

    对原型方式的改进:

      使用原型+构造函数方式来定义对象,对象之间的属性互不干扰,各个对象间共享同一个方法

    <script type="text/javascript">
    //使用原型+构造函数方式来定义对象
    
    function Person()
    {
           this.username = new Array();
           this.password = "123";
    }
    
    Person.prototype.getInfo = function()
    {
           alert(this.username + ", " + this.password);
    }
    
    var p = new Person();
    var p2 = new Person();
    
    p.username.push("zhangsan");
    p2.username.push("lisi");
    
    p.getInfo();
    p2.getInfo();
    
    </script>

     

    五.动态原型方式

      在构造函数中通过标志量让所有对象共享一个方法,而每个对象拥有自己的属性。

    <script type="text/javascript">
    
    function Person()
    {
           this.username = "zhangsan";
           this.password = "123";
    
           if(typeof Person.flag == "undefined")
           {
                  //此块代码应该只在第一次调用的时候执行
                  alert("invoked");
    
                  Person.prototype.getInfo = function()
                  {
                         //这个方法定义在原型中,会被每一个对象所共同拥有
                         alert(this.username + ", " + this.password);
                  }
    
                  Person.flag = true;//第一次定义完之后,之后的对象就不需要再进来这块代码了
    
           }
    }
    
    var p = new Person();
    var p2 = new Person();
    
    p.getInfo();
    p2.getInfo();
    
    </script>

    参考资料

      圣思园张龙老师Java Web视频教程。

      W3School JavaScript教程:http://www.w3school.com.cn/js/index.asp

      英文版:http://www.w3schools.com/js/default.asp

     

  • 相关阅读:
    Web前段学习索引
    Python学习索引
    Centos7下安装Docker(详细的新手教程)
    Django部署阿里云服务器(nginx+uwsgi)
    (转)Mongo db 与mysql 语法比较
    (转)mongo基本常用命令
    python操作mongodb的基本操作命令
    http响应码
    python回调函数
    Flask框架的使用
  • 原文地址:https://www.cnblogs.com/mengdd/p/3697255.html
Copyright © 2020-2023  润新知