JavaScript中定义对象的几种方式

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

在JavaScript中定义对象可以采用以下5种方式(附加改进方式):

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

2.工厂方式

3.构造函数方式

4.原型(“prototype”)方式

5.动态原型方式


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

<span style="font-size:14px;"><script   type="text/javascript">
        var obj=new Object()       //obj={}  也可以这样声明对象;
        obj.name="zhangq0123";
        obj.outName=function(name){
                this.name=name;
                console.log(this.name);
         }
         obj.outName("zhangq");
</script></span>

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


二.工厂方式

<span style="font-size:14px;"><script type=text/javascript>
function createObject(){
      var obj= new Object();
       obj.username= "zhangq0123";
       obj.password="123";
       obj.getMessage= function(){
              console.log(this.username+","+this.password);
        }
        return obj;
}
var obj1= createObject();
var obj2= createObject();
obj1.getMessage();   //zhangq0123,123
</script></span>

改进一:带参数的构造函数:

<script type=text/javascript>
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 obj1 = createObject("zhangq0123", "123");
obj1.get();
</script>
改进二:让多个对象共享函数对象,这样,不用每个对象都生成一个函数对象。

<span style="font-size:14px;"><script  type=text/javascript>
function  getMassage(username,password){
     console.log(this.username+","+this.password);
}

//函数对象只有一份。
function   createObject(){
    var obj=new  Object();
     obj.username= username;
     obj.password= password;
     obj.getMessage= getMassege;    //每一个对象的函数对象都指向同一个函数对象。
      return  obj;
}
var obj1= createObject("zhangq0123","0123");
var  obj2 createObject("zhangq","123");
</script></span>
优点:让一个函数对象被多个对象所共享,而不是每一个对象拥有一个函数对象。

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


三.构造函数方式

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

<span style="font-size:14px;"><script  type="text/javascript">
function Person()
{
       //在执行第一行代码前,js引擎会为我们生成一个对象
       this.username = "zhangq0123";
       this.password = "123";
       this.getMessage = function()
       {
              console.log(this.username + ", " + this.password);
       } 
       //此处有一个隐藏的return语句,用于将之前生成的对象返回
       //只有在后面用new的情况下,才会出现注释所述的这两点情况

}

//生成对象
var zhangq = new Person();//用了new
zhangq.getMessage();  //zhangq0123,123
</script> </span>
改进一:加上参数:
<span style="font-size:14px;"><script  type="text/javascript">
function Person(username, password)
{
       this.username = username;
       this.password = password;
       this.getMessage = function()
       {
              console.log(this.username + ", " + this.password);
       }
}
var zhnagq = new Person("zhangq0123", "123");
zhangq.getMessage();   //zhango123,123
</script></span>

四.原型(“prototype”)方式

<span style="font-size:14px;"><script>
function Person()
{
}

Person.prototype.username = "zhangq0123";
Person.prototype.password = "123";

Person.prototype.getMessage = function()
{
       console.log(this.username + ", " + this.password);
}
var zhangq1 = new Person();
var zhangq2 = new Person();

zhangq1.username = "zhangq";

zhangq1.getMessage();   //zhangq, 123
zhangq2.getMessage();   //zhangq0123, 123
</script></span>
使用原型存在的缺点:

1.不能给函数(如Person)传参数;2.有可能会导致程序的错误。

改进一:username改为数组后;

<span style="font-size:14px;">function Person()
{
}

Person.prototype.username = new Array();
Person.prototype.password = "123";
Person.prototype.getMessage = function()
{
       console.log(this.username + ", " + this.password);
}

var zhangq1 = new Person();
var zhngaq2 = new Person();

zhangq1.username.push("zhangq0123");
zhangq1.username.push("zhangq01234");
zhangq1.password = "456";

person.getMessage(); //输出:zhangq0123,zhangq01234, 456
person2.getMessage(); //输出:zhangq0123,zhangq01234, 123

//虽然没有对person2对象进行修改,但是它的name和person是一样的,即为zhangq0123,zhangq01234。</span>
注:这是因为使用原型方式,person和person2指向的是同一个原型,即对应了同样的属性对象。 对于引用类型(比如数组),两个对象指向了同一个引用,所以对一个所做的更改会影响另一个。 而对于字符串(字面常量值),重新赋值之后就指向了另一个引用,所以二者的修改互不影响。

改进一:对原型方式改进(建议使用这定义对象的方式)

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

<span style="font-size:14px;"><script type="text/javascript">
//使用原型+构造函数方式来定义对象

function Person()
{
       this.username = new Array();
       this.password = "123";
}

Person.prototype.getMessage = function()
{
       console.log(this.username + ", " + this.password);
}

var zhangq1 = new Person();
var zhangq2 = new Person();

zhangq1.username.push("zhangq0123");
zhangq2.username.push("zhangq01234");

zhangq1.getMessage();    //zhangq0123, 123
zhangq2.getMessage();   //zhangq01234, 123

</script></span>

五.动态原型方式

<span style="font-size:14px;"><script type="text/javascript">
function Person()
{
       this.username = "zhang0123";
       this.password = "123";

       if(typeof Person.flag == "undefined")
       {
              //此块代码应该只在第一次调用的时候执行
             console.log("invoked");

             Person.prototype.getMessage = function()
              {
                     //这个方法定义在原型中,会被每一个对象所共同拥有
                     console.log(this.username + ", " + this.password);
              }
              Person.flag = true;//第一次定义完之后,之后的对象就不需要再进来这块代码了

       }
}

var zhangq1 = new Person();
var zhangq2 = new Person();

zhangq1.getMessage();    //zhangq0123,123
zhangq2.getMessage();    //zhangq0123,123

</script></span>

PS:猿猿们有什么想法可以留言给我呦!





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值