zoukankan      html  css  js  c++  java
  • JavaScript 创建对象的几种模式

    在JavaScript中虽说可以用Object的构造函数或者字面量创建单个对象,但是用这些方式来创建多个对象时就有一个明显的缺点,产生了大量的重复代码。为解决这些问题,许多模式就应运而生。

    1. 工厂模式

    由于在ECMAScript中无法创建类,所以就发明了一种函数,用来封装以特定接口创建对象的细节。

    但是以这种方式创建的对象没有解决对象识别问题,即怎样知道一个对象的类型。

    function createPerson(name,age,job)
    {
    var o = new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayHellow=function()
    {alert("Hellow"+o.name)};
    return o;
    }
    
    var person1 = createPerson("Jack",34,"Doctor");

    2. 构造函数模式

    这种方式创建的对象都是属于同一类型的,下面的例子中,所有的对象都是Person类型。

    function Person(name,age,job)
    {
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName = function()
       {
       alert("Hello, "+this.name);
       }
    }
    
    var person1 = new Person("Jack",24,"Doctor");
    var person2 = new Person("Simon",34,"Teacher");
    
    alert(person1 instanceof Object); // true
    alert(person1 instanceof Person); // true
    alert(person2 instanceof Object); // true
    alert(person2 instanceof Person); // true

    但是这个模式也有缺点,那就是每个方法都要在每个对象的实例中重新创建一遍。就如上面的例子,person1 和person2的sayName方法其实不是Function的同一个实例,是位于两个不同位置的函数指针。

    所以可以改进下:

    function Person(name,age,job)
    {
    this.name=name;
    this.age=age;
    this.job=job;
    this.sayName = sayName;
    }
    function sayName()
    {
       alert("Hello, "+this.name);
    }
    
    var person1 = new Person("Jack",24,"Doctor");
    var person2 = new Person("Simon",34,"Teacher");
    
    alert(person1 instanceof Object); // true
    alert(person1 instanceof Person); // true
    alert(person2 instanceof Object); // true
    alert(person2 instanceof Person); // true

    3. 原型模式

    想弄明白这个模式,必须要想理解prototype.

    这个模式有个很大的问题,就是所有对象的属性和方法都是共享的,但是我们可能仅仅想让Person类共享这个sayName 方法,大家应该都想到了,可以用构造函数模式+原型模式来解决这个问题。

    function Person(){}
    Person.prototype.name="Jack";
    Person.prototype.age=33;
    Person.prototype.job="IT";
    Person.prototype.sayName = function(){alert("Hellow"+ this.name);};
    
    // 字面量写法
    function Person(){}
    Person.prototype =
    {
    name: "Jack",
    age: 33,
    job: "IT",
    sayName=function(){alert("Hellow "+this.name);}
    }

    4. 组合使用构造函数模式和原型模式

    用构造函数定义实例属性,存放不共享的数据,用原型模式定义共享的方法和属性,这样可以尽最大可能减少内存开销。

    有点类似于c#类的实例成员和静态成员,但只是像。

    这中模式是目前用的最广泛,认可太最高的。

    function Person(name,age,job)
    {
      this.name=name;
      this.age=age;      
      this.job=job;  
      this.friends=["Toby","Linford"];  
    }
    Person.prototype=
    {
     constructor: Person,
     sayName: function(){alert(this.name);}
    }
    
    var person1 = new Person("Jack",33,"SDE");
    var person2 = new Person("Lucy",25,"Teacher");
    
    person1.friends.push("Jim");
    
    alert(person1.friends); // Toby,Linford,Jim
    alert(person2.friends); // Toby,Linford
    
    alert(person1.friends==person2.friends); // false
    alert(person1.sayName==person2.sayName); //true

    5.动态原型模式

    function Person(name,age,job)
    {
      this.name=name;
      this.age=age;      
      this.job=job;  
      if(typeof sayName != "function")
      {
        Person.prototype.sayName=function()
        {
           alert(this.name);
         }
       };
    }

    6. 寄生构造函数模式

    其基本思想就是一个函数,该函数的作用仅仅就是封装创建对象的代码,然后再返回新创建的对象。

    function createPerson(name,age,job)
    {
    var o = new Object();
    o.name=name;
    o.age=age;
    o.job=job;
    o.sayHellow=function()
    {alert("Hellow"+o.name)};
    return o;
    }
    
    var person1 = createPerson("Jack",34,"Doctor");

    从上面代码看来和工厂模式是一样的。但是这个模式可以在特殊的情况为对象(特别是内置的对象,如Array)添加构造函数。

    7.稳妥构造函数模式

    和寄生构造函数模式类似,但有两个不同点,一是创建对象的实例方法不引用this,二是不使用new 调用构造函数。

    function Person(name, age, job)
    {
      //定义要返回的对象
      var o = new Object();
      //定义私有变量和方法
    
      //添加方法
      o.sayName=function(){alert(name);};
      
      return o;
    }

    在上面的例子中,只有通过sayName才可以访问name.

  • 相关阅读:
    HTML5 JSDOM
    svn 基本操作
    Flex布局
    git上传布置代码 git优势
    jsonp, json区别
    require.js 模块化简单理解
    @vue/cli 3 安装搭建及 webpack 配置
    npm 常用命令 使用命令删除 node_modules 包
    package.json字段分析
    rem适配方案
  • 原文地址:https://www.cnblogs.com/Linford-Xu/p/4110797.html
Copyright © 2011-2022 走看看