zoukankan      html  css  js  c++  java
  • 【JavaScript学习】JavaScript对象创建

    1.最简单的方法,创建一个对象,然后添加属性

     1 var person = new Object();
     2 person.age = 23;
     3 person.name = "David";
     4 person.job = "student";
     5 person.sayName = function ()
     6 {
     7        alert(this.name);
     8 };
     9 
    10 //类似于定义键值对或者json数据格式的定义方法.
    11 var person =
    12 {
    13      age:23,
    14      name:"David",
    15      job:"student",
    16      sayName:function()
    17      {
    18          alert(this.name);
    19      }
    20 };

    该方法简单明了,缺点就是当要创建多个同类型的对象时,重复性的代码较多.

    2.解决方法1中的问题,借鉴许多软件设计的思想,引入工厂模式,即构造一个创建对象的工厂函数,实现对象创建的功能.

     1 function createPerson(name,age,job)
     2 {
     3        var o = new Object();
     4        o.name = name;
     5        o.age = age;
     6        o.job = job;
     7        o.sayName = function()
     8        {
     9                alert(this.name);
    10        };
    11        return o;
    12 }
    13 var person = createPerson("David",23,"student");

    该方法解决了代码重复的问题,可以利工厂函数创建出多个对象.但此方法返回的对象都是Object类型,不能标识创建的对象的类型属性.

    3.构造函数模式,创建构造函数,结合new操作符可以创建对象

     1 function Person(name,age,job)
     2 {
     3     this.name = name;
     4     this.age = age;
     5     this.job = job;
     6     this.sayName = function()
     7     {
     8         alert(this.name);
     9     }
    10 }
    11 var person1 = new Person("David",23,"student");
    12 var person2 = Person("Bill",21,"Boss");
    13 person1.sayName();  //显示David
    14 person2.sayName(); //显示undefined
    15 sayName();          //显示Bill

    person1 结合new 操作创建了一个对象实例,但person2没有结合new,直接调用Person(name,age,job)函数,此时,函数的作用域里的this指的是window,因而出现后两行的显不结果.安全的构造函数可以避免出现上述的问题

     1 function Person(name,age,job)
     2 {
     3      if(this instanceof Person)
     4      {
     5           this.name = name;
     6           this.age = age;
     7           this.job = job;
     8           this.sayName = function()
     9           {
    10               alert(this.name);
    11           }
    12      }
    13      else
    14          return new Person(name,age,job);
    15 }

    this instanceof Person  检测当前this是否指向到Person对象. 这样改进后,将不会出上面描述的问题.关键是理解this是指向当前执行环境的,关于函数的执行环境以及作用域链,以后再作介绍.一般类型的方法是一样的,可以共享,但使用该方法,每创建一个对象,都会创建一个方法的副本,产生代码的重复性.

    4.解决该问题,可以把方法置于构造函数体外定义,构造函数内只需要引用在构造函数外定义的函数即可.

     1 function Person(name,age,job)
     2 {
     3     this.name = name;
     4     this.age = age;
     5     this.job = job;
     6     this.sayName = sayName;
     7 }
     8 
     9 function sayName()
    10 {
    11     alert(this.name);
    12 }

    这样可以解决方法共享的问题,但会引入其他问题,这样将导致global scope里将会有许有方法,使用global scope过于庞大,这样不便于代码管理,方法和相应的属性分开.

    5.原型模式.

     1 function Person(){}
     2 Person.prototype.name = "David";
     3 Person.prototype.age = 23;
     4 Person.prototype.job = "student";
     5 Person.prototype.sayName = function()
     6 {  
     7     alert(this.name);
     8 };
     9 var person1 = new Person();
    10 var person2 = new Person();

    通过设置构造函数的原型,来达到对象中属性和方法的共享,person1和person2中对应的属性和方法都是一样的. 虽然这种方法,实现了代码共享,减少了代码的重复,但并不符合人们的需求,一般都是需要各个对象既有共享的方法和属性,又有各自的特点和属性.而且这种方法不能传递初始化参数,默认构造的对象都具有与原型相同的属性.

    6.原型和构造函数混合模式  利用原型来设置方法,达到方法的共享,利用构造函数来实现属性的设置,支持初始化参数传递,达到属性的个性化

     1 function Person(name,age,job)
     2 {
     3     this.name = name;
     4     this.age = age;
     5     this.job = job;
     6 }
     7 Person.prototype = {
     8     constructor:Person,
     9     sayName:function()
    10     {
    11         alert(this.name);
    12     }
    13 };
    14 var person1 = new Person("David",23,"student");
    15 var person2 = new Person("Bill",21,"Boss");

    这样person1和person2对应的属性不共享,但方法sayName共享.该方法基本可以满足一般用户创建对象的需求.该方法存在一点不好,就是方法和属性要分开设置,而且在利用原型设置方法时,若是重写原型,则必须指定constructor为构造函数,若是只设置相应的属性,如Person.prototype.sayName = function(){};则不需要指定constructor属性.

    7.动态原型模式 可以将属性和方法设置一起置于构造函数内.

     1 function Person(name,age,job)
     2 {
     3     this.name = name;
     4     this.age = age;
     5     this.job = job;
     6   
     7   if(typeof this.sayName != "function")
     8     {
     9          Person.prototype.sayName = function()
    10          {
    11              alert(this.name);
    12          };
    13     }
    14  }

    检测this.sayName是否已经定义,若定义了,则不用设置原型.否则,设置原型定义sayName函数.这种方法同样可以达到属性个性化,方法共享的要求

           总结,以上就是几种关于对象创建的方法的总结,逐步完善,从每种方法存在的问题出发,从而寻找更好的解决方法,这样可以进一步的理解javascript中各种机制设计的最初目的.

  • 相关阅读:
    (转) 网络流之最大流算法(EdmondsKarp)
    如何在面试中发现优秀程序员
    Java中Volatile关键字详解
    比AtomicLong还高效的LongAdder 源码解析
    AtomicInteger的用法
    synchronized详解
    Java内部锁的可重用性(Reentrancy)
    Java可重入锁
    关于原生javascript的this,this真是个强大的东东
    js时间戳怎么转成日期格式
  • 原文地址:https://www.cnblogs.com/dwdxdy/p/3215212.html
Copyright © 2011-2022 走看看