定义JavaScript类:工厂模式、构造函数模式、原型模式、构造函数原型模式、动态原型模式

简介:

1    工厂模

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script type= "text/javascript" >
         //通过包装函数封装模具
         function  wrapBook(title,pages){
             var  book =  new  Object ();
             //申明属性并接收参数
             book.title = title;
             book.pages = pages;
             book.what =  function (){
                 alert( this .title+ ":" + this .pages);
             }
             return  book;    //返回初始化后的对象
         }
          window.onload =  function (){
              //调用模具快速生产
              //var book1 = wrapBook("JavaScript权威指南",600);
              //var book2 = wrapBook("Dojo权威指南",390);
              var  book1 =  new  wrapBook( "JavaScript权威指南" , 600 );
              var  book2 =  new  wrapBook( "Dojo权威指南" , 390 );
              book1.what();
              book2.what();
              console.dir(book1);
              console.dir(book2);
          }
     </script>

 问题:上面方法what()封装在图书模具函数wrapBook结构中,这样每生产一本书,该函数就被创建一次,也就是说,每本书都有一个相同的方法,造成资源浪费。

  解决:把方法what()分离出来,在模具中引用该方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script type= "text/javascript" >
         //申明一个全局变量
         what =  function  (){
             alert( this .title+ ":" + this .pages);
         }
         //通过包装函数封装模具
         function  wrapBook(title,pages){
             var  book =  new  Object ();
             //申明属性并接收参数
             book.title = title;
             book.pages = pages;
             book.what = what;    //引用全局方法的引用指针
             return  book;    //返回初始化后的对象
         }
          window.onload =  function (){
              //调用模具快速生产
              //var book1 = wrapBook("JavaScript权威指南",600);
              //var book2 = wrapBook("Dojo权威指南",390);
              var  book1 =  new  wrapBook( "JavaScript权威指南" , 600 );
              var  book2 =  new  wrapBook( "Dojo权威指南" , 390 );
              book1.what();
              book2.what();
              console.dir(book1);
              console.dir(book2);
          }
     </script>


2    构造函数模式


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//构造函数模型
         function  Book(title,pages){
             //构造函数属性
             this .title = title;
             this .pages = pages;
             //构造函数方法
             this .what =  function  (){
                 alert( this .title+ ":" + this .pages);
             }
         }
          window.onload =  function (){
              //实例化构造函数,并传递参数
              var  book1 =  new  Book( "JavaScript权威指南" , 600 );
              var  book2 =  new  Book( "Dojo权威指南" , 390 );
              book1.what();
              book2.what();
              console.dir(book1);
              console.dir(book2);
          }
     </script>


      备注:构造函数模式只能使用new运算符进行调用,不能使小括号()来调用。

       问题:类似于工厂模式,造成what()方法重复创建。


3    原型模式

     采用函数的prototype属性来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script type= "text/javascript" >
        //使用构造函数定义一个空类
        function  Book(){ }
       //为原型申明属性并初始化
        Book.prototype.title =  "图书名称" ;
        Book.prototype.pages =  120 ;
        //为原型申明一个方法
        Book.prototype.what =  function  (){
                alert( this .title+ ":" + this .pages);
        }
         window.onload =  function (){
             //实例化构造函数,并传递参数
             var  book1 =  new  Book();
             var  book2 =  new  Book();
             book1.what();
             book2.what();
             console.dir(book1);
             console.dir(book2);
         }
    </script>


4    构造函数原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type= "text/javascript" >
         //构造函数模式设计
         function  Book(title,pages){
             //构造函数属性
             this .title = title;
             this .pages = pages;
         }
         //原型模式设计
         Book.prototype.what =  function  (){
                 alert( this .title+ ":" + this .pages);
         }
          window.onload =  function (){
              //实例化构造函数,并传递参数
              var  book1 =  new  Book( "JavaScript权威指南" , 600 );
              var  book2 =  new  Book( "Dojo权威指南" , 390 );
              book1.what();
              book2.what();
              console.dir(book1);
              console.dir(book2);
          }
     </script>

   备注:推荐采用此模式。


5     动态原型模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type= "text/javascript" >
         //构造函数模式设计
         function  Book(title,pages){
             //构造函数属性
             this .title = title;
             this .pages = pages;
             //原型模式设计,位于类的内部
             Book.prototype.what =  function  (){
                 alert( this .title+ ":" + this .pages);
             }
         }
          window.onload =  function (){
              //实例化构造函数,并传递参数
              var  book1 =  new  Book( "JavaScript权威指南" , 600 );
              var  book2 =  new  Book( "Dojo权威指南" , 390 );
              book1.what();
              book2.what();
              console.dir(book1);
              console.dir(book2);
          }
     </script>

   问题:当每次实例化时,类中包含的原型方法就会被创建一次,造成资源浪费。

   解决:安装一个判断开关,检测该方法是否已经创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script type= "text/javascript" >
        //构造函数模式设计
        function  Book(title,pages){
            //构造函数属性
            this .title = title;
            this .pages = pages;
            //创建原型方法的锁,如果不存在,就创建该方法
            if ( typeof  Book.isLock ==  "undefined" ){
                Book.prototype.what =  function  (){
                    alert( this .title+ ":" + this .pages);
                };
                //创建原型方法后,把锁锁上,避免重复创建
                Book.isLock =  true ;
            }
        }
         window.onload =  function (){
             //实例化构造函数,并传递参数
             var  book1 =  new  Book( "JavaScript权威指南" , 600 );
             var  book2 =  new  Book( "Dojo权威指南" , 390 );
             book1.what();
             book2.what();
             console.dir(book1);
             console.dir(book2);
         }
    </script>


       总结:目前使用最广泛的是混合的构造函数/原型方式。此外,动态原型方法也很流行,在功能上与构造函数/原型方式等价。可以采用这两种方式中的任何一种。不过不要单独使用经典的构造函数或原型方式,因为这样会给代码引入问题。







     本文转自stock0991 51CTO博客,原文链接:http://blog.51cto.com/qing0991/1363513,如需转载请自行联系原作者










相关文章
|
2月前
|
JavaScript
js开发:请解释什么是ES6的类(class),并说明它与传统构造函数的区别。
ES6的类提供了一种更简洁的面向对象编程方式,对比传统的构造函数,具有更好的可读性和可维护性。类使用`class`定义,`constructor`定义构造方法,`extends`实现继承,并可直接定义静态方法。示例展示了如何创建`Person`类、`Student`子类以及它们的方法调用。
23 2
|
2月前
|
JavaScript 前端开发
js开发:请解释原型继承和类继承的区别。
JavaScript中的原型继承和类继承用于共享对象属性和方法。原型继承利用原型链查找属性,节省内存但不支持私有成员。类继承通过ES6的class和extends实现,支持私有成员但占用更多内存。两者各有优势,适用于不同场景。
22 0
|
2月前
|
JavaScript
JS数组增删方法的原理,使用原型定义
JS数组增删方法的原理,使用原型定义
|
1天前
|
设计模式 JavaScript 前端开发
js设计模式-观察者模式与发布/订阅模式
观察者模式和发布/订阅模式是JavaScript中的两种设计模式,用于处理对象间的通信和事件处理。观察者模式中,一个主题对象状态改变会通知所有观察者。实现包括定义主题和观察者对象,以及在主题中添加、删除和通知观察者的功能。发布/订阅模式则引入事件管理器,允许发布者发布事件,订阅者通过订阅接收通知。
|
13天前
|
JavaScript 前端开发 IDE
【JavaScript与TypeScript技术专栏】JavaScript与TypeScript混合编程模式探讨
【4月更文挑战第30天】本文探讨了在前端开发中JavaScript与TypeScript的混合编程模式。TypeScript作为JavaScript的超集,提供静态类型检查等增强功能,但完全切换往往不现实。混合模式允许逐步迁移,保持项目稳定性,同时利用TypeScript的优点。通过文件扩展名约定、类型声明文件和逐步迁移策略,团队可以有效结合两者。团队协作与沟通在此模式下至关重要,确保代码质量与项目维护性。
|
14天前
|
JavaScript 前端开发
实现一个JavaScript动态日期功能
实现一个JavaScript动态日期功能
|
15天前
|
JavaScript 前端开发
【专栏】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表
【4月更文挑战第29天】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表。它接受两个参数:上下文对象和参数数组。理解`apply`有助于深入JS运行机制。文章分三部分探讨其原理:基本概念和用法、工作原理详解、实际应用与注意事项。在应用中要注意性能、参数类型和兼容性问题。`apply`可用于动态改变上下文、传递参数数组,甚至模拟其他语言的调用方式。通过深入理解`apply`,能提升代码质量和效率。
|
22天前
|
JavaScript 前端开发 索引
JavaScript中的正则表达式:使用与模式匹配
【4月更文挑战第22天】本文介绍了JavaScript中的正则表达式及其模式匹配,包括字面量和构造函数定义方式,以及`test()`、`match()`、`search()`和`replace()`等匹配方法。正则表达式由元字符(如`.`、`*`、`[]`)和标志(如`g`、`i`)组成,用于定义搜索模式。文中还分享了正则使用的技巧,如模式分解、非捕获分组和注释。掌握正则表达式能提升文本处理的效率和代码质量。
|
24天前
|
存储 JavaScript 前端开发
JavaScript的数据类型主要分为两大类:基本数据类型和引用数据类型
【4月更文挑战第20天】JavaScript的数据类型主要分为两大类:基本数据类型和引用数据类型
22 6
|
1月前
|
前端开发 JavaScript 数据可视化
使用JavaScript实现复杂功能:动态数据可视化的构建
使用JavaScript实现复杂功能:动态数据可视化的构建