• 面向对象的程序设计——创建对象


    一、工厂模式

      工厂模式解决了创建多个相似对象的问题,但没有解决对象识别的问题(即怎样知道一个对象的类型)。

     1 //工厂模式创建对象
     2 function createPerson(name ,  age , job){
     3     var o = new Object();
     4     o.name = name;
     5     o.job = job;
     6     o.sayName = function(){
     7         alert(this.name);
     8     }
     9     return o;
    10 }
    11 var person2 = new createPerson("Lily" , 21 , "Worker");
    12 var person3 = new createPerson("Lulu" , 21 , "Student");
    13 person2.sayName();//Lily
    14 person3.sayName();//Lulu 

     

    二、构造函数模式

      主要是利用构造函数创建对象,缺点是当需要定义很多方法是,就要定义很多全局函数,那自定义的引用类型就丝毫没有封装性可言了。

     1 //构造函数模式创建对象
     2 function Person(name , age , job) {
     3     this.name = name;
     4     this.age = age;
     5     this.job = job;
     6     this.sayName = sayName;//为了避免创建两个完全同样任务的Function实例
     7 }
     8 function sayName(){
     9     alert(this.name);
    10 }
    11 var person2 = new Person("Lily" , 21 , "Worker");
    12 var person3 = new Person("Lulu" , 21 , "Student");
    13 person2.sayName();//Lily
    14 person3.sayName();//Lulu

     

    三、原型模式

      使用原型对象的好处是可以让所以对象实例共享它所包含的属性和方法。

     1 //原型模式创建对象
     2 function Person() {
     3 }
     4 Person.prototype.name = "Lily";
     5 Person.prototype.age = 21;
     6 Person.prototype.job = "Student";
     7 Person.prototype.sayName = function(){
     8     alert(this.name);
     9 }
    10 var person2 = new Person();
    11 var person3 = new Person();
    12 
    13 person2.name = "Lulu";
    14 alert(person2.name);  //Lulu -- 来自实例
    15 alert(person3.name);  //Lily --来自原型
    16 delete person2.name;
    17 alert(person2.name);  //Lily --来自原型

     

    更简单的原型语法:

     1 function Person(){
     2 }
     3 Person.prototype = {
     4     constructor: Person ,name: "lily",
     5     age: 22,
     6     job: "Student",
     7     sayName: function(){
     8         alert(this.name);
     9     }
    10 };

    注:重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系。

     

    尽管原型模式看似完美,但对于引用类型值的属性来说,问题就比较突出了,如:

     1 function Person() {
     2 }
     3 Person.prototype.name = "Lily";
     4 Person.prototype.age = 21;
     5 Person.prototype.job = "Student";
     6 Person.prototype.friends = ["a" , "b"];
     7 Person.prototype.sayName = function(){
     8     alert(this.name);
     9 };
    10 var person2 = new Person();
    11 var person3 = new Person();
    12 
    13 person2.friends.push("c");
    14 alert(person2.friends);  //a,b,c
    15 alert(person3.friends);  //a,b,c

      问题很明显,实例一般都是要有属于自己的全部属性的,但上面的结果很明显就出现问题了。如果初衷是所有实例共享一个数组时,那这个问题便不存在了。要解决这个问题,可以利用以下的方法,即组合使用构造函数模式与原型模式。

     1 function Person(name , age , job){
     2     this.name = name;
     3     this.age = age;
     4     this.job = job;
     5     this.friends = ["a" , "b"];
     6 }
     7     Person.prototype = {
     8         constructor:Person,
     9         sayName: function(){
    10         alert(this.name);
    11     }
    12 }
    13 
    14 var person2 = new Person("lily" , 21 , "Student");
    15 var person3 = new Person("suda" , 21 , "Student");
    16 person2.friends.push("c");
    17 alert(person2.friends);  //a,b,c
    18 alert(person3.friends);  //a,b
    19 alert(person3.friends == person2.friends); //false
    20 alert(person3.sayName == person2.sayName); //true             

     

    还有两种模式,分别是寄生构造函数模式和稳妥构造模式,不是很常用,所以就不讲了。

    参考《JavaScript高级程序设计》

     

  • 相关阅读:
    basic-linux
    巧用border属性
    git常用操作笔记
    如何删除github里的项目
    常用css3属性的ie兼容查看
    新建pc端页面的模板
    HTML5 Shiv--解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
    进程和线程
    C++对象模型---第 4 章 Function语意学
    C++对象模型---第 3 章 Data语意学
  • 原文地址:https://www.cnblogs.com/daheiylx/p/8797060.html
Copyright © 2020-2023  润新知