javascript设计模式--封装和信息隐藏(下)

简介:   今天讲解的内容是高级模式(Advanced Patterns),如何实现静态方法和属性,常量还有其他一些知识点。   1.静态方法和属性   其实要实现这一功能还是要借助于闭包。在上一讲中的第三种实现方式也使用了闭包,但通过那种实现,内部属性和方法是实例级别的。

  今天讲解的内容是高级模式(Advanced Patterns),如何实现静态方法和属性,常量还有其他一些知识点。

  1.静态方法和属性

  其实要实现这一功能还是要借助于闭包。在上一讲中的第三种实现方式也使用了闭包,但通过那种实现,内部属性和方法是实例级别的。

var book1=new Book('isbn1','title1','author1');
var book2=new Book('isbn2','title2','author2');

alert(book1.getTitle()); //输出title1
alert(book2.getTitle()); //输出title2

  通过上面的例子可以看出,创建的book1和book2有独立的私有属性,对book2的私有属性赋值不会影响到book1。

  那么怎么才能实现类级别的私有属性和方法呢,这里除了需要使用闭包之外,还需要使用到匿名函数。代码如下:代码1

var Book = (function() {
  // Private static attributes.
  var numOfBooks = 0;
  // Private static method.
  function checkIsbn(isbn) {
    ...
  }

  // Return the constructor.   return function(newIsbn, newTitle, newAuthor) { // implements Publication     // Private attributes.     var isbn, title, author;     // Privileged methods.     this.getIsbn = function() {       return isbn;     };     this.setIsbn = function(newIsbn) {       if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');       isbn = newIsbn;     };     this.getTitle = function() {       return title;     };     this.setTitle = function(newTitle) {       title = newTitle || 'No title specified';     };     this.getAuthor = function() {       return author;     };     this.setAuthor = function(newAuthor) {       author = newAuthor || 'No author specified';     };     this.getNumOfBooks = function(){
      return numOfBooks;
    };

    // Constructor code.     numOfBooks++; // Keep track of how many Books have been instantiated     // with the private static attribute.     if(numOfBooks > 50) throw new Error('Book: Only 50 instances of Book can be '                         + 'created.');     this.setIsbn(newIsbn);     this.setTitle(newTitle);     this.setAuthor(newAuthor);   } })();
// Public static method. Book.convertToTitleCase = function(inputString) {   ... };
// Public, non-privileged methods. Book.prototype = {   display: function() {     ...   } };

  对匿名函数不了解的同学可以自己去查阅相关资料。其实上面的代码等价于:代码2

var tempBook = function() {
  // Private static attributes.
  var numOfBooks = 0;
  // Private static method.
  function checkIsbn(isbn) {
    ...
  }
   // Return the constructor.
  return function(newIsbn, newTitle, newAuthor) { // implements Publication
    ...
  } };
var Book = tempBook();

// Public static method. Book.convertToTitleCase = function(inputString) {   ... }; // Public, non-privileged methods. Book.prototype = {   display: function() {     ...   } };

  那么如果再执行之前的代码会有什么效果呢:

var book1=new Book('isbn1','title1','author1');
var book2=new Book('isbn2','title2','author2'); 
alert(book1.getNumOfBooks()); //输出 2
alert(book2.getNumOfBooks()); //输出 2

  为什么会有这样的效果呢,其实通过匿名函数加闭包这种组合模式,numOfBooks已经是真正意义上的私有静态变量的,无论你创建多少个Book的实例,系统中也只有一个numOfBooks变量。有人或许疑问,为什么每创建一个新的Book实例的时候,没有多生成一个numOfBooks呢?

  我们从代码2上可以找到答案,其实我们创建的Book实例是执行了tempBook()方法,而不是new tempBook对象!tempBook对象在系统中只会运行一次,所以他内部的numOfBooks变量也就只有一份。每次执行new Book(‘...’,‘...’,‘...’);的时候,其实只是执行了tempBook中的function(newIsbn, newTitle, newAuthor),并没有创建新的tempBook对象,所有Book实例在使用getNumOfBooks方法时调用到的都是同一个numOfBooks。

  不知道我的讲解是否清楚,希望对大家有帮助。

 

  2.常量

   其实这部分还真没什么好讲的,只要你理解了上面的内容,在匿名函数内部实现一个类似于numOfBooks的变量,在整个初始化过程不对他进行修改,也不提供任何修改的方法,同时提供一个类似于getNumOfBooks方法供外部访问它,就ok了,代码我就懒的写了。

 

  3.使用封装的好处和弊端

  好处:

  可以实现对代码的控制,公布想公开的隐藏不想公开的信息。同时也方便你重构代码,你创建的对象的使用者不会因为你修改内部对象(私有的变量或者方法)而影响别人正常的使用。面相接口编程可以实现代码之间的松耦合。

  弊端:

  1.测试内部变量很困难,最好的办法是通过测试公共方法实现对内部方法的测试。

  2.因为复杂的作用域导致代码调试变的很困难。

 

目录
相关文章
|
27天前
|
设计模式 JavaScript 算法
浅谈几种js设计模式
设计模式是软件开发中的宝贵工具,能够提高代码的可维护性和扩展性。通过单例模式、工厂模式、观察者模式和策略模式,我们可以解决不同场景下的实际问题,编写更加优雅和高效的代码。
28 8
|
2月前
|
设计模式 数据安全/隐私保护
Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式
这篇文章介绍了在Next.js框架下,如何处理中后台管理系统中特殊页面(如登录页)不包裹根布局(RootLayout)的问题。作者指出Next.js的设计理念是通过布局的嵌套来创建复杂的页面结构,这虽然保持了代码的整洁和可维护性,但对于特殊页面来说,却造成了不必要的布局包裹。文章提出了一个解决方案,即通过判断页面的skipGlobalLayout属性来决定是否包含RootLayout,从而实现特殊页面不包裹根布局的目标。
123 33
|
4月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
67 2
|
5月前
|
机器学习/深度学习 自然语言处理 JavaScript
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
在信息论、机器学习和统计学领域中,KL散度(Kullback-Leibler散度)是量化概率分布差异的关键概念。本文深入探讨了KL散度及其相关概念,包括Jensen-Shannon散度和Renyi散度。KL散度用于衡量两个概率分布之间的差异,而Jensen-Shannon散度则提供了一种对称的度量方式。Renyi散度通过可调参数α,提供了更灵活的散度度量。这些概念不仅在理论研究中至关重要,在实际应用中也广泛用于数据压缩、变分自编码器、强化学习等领域。通过分析电子商务中的数据漂移实例,展示了这些散度指标在捕捉数据分布变化方面的独特优势,为企业提供了数据驱动的决策支持。
466 2
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
|
5月前
|
JavaScript 前端开发 UED
JavaScript 地址信息与页面跳转
JavaScript 地址信息与页面跳转
63 0
|
5月前
|
JavaScript 前端开发 UED
JavaScript 地址信息与页面跳转
JavaScript 地址信息与页面跳转
97 1
|
5月前
|
前端开发 JavaScript Go
JS基础:输出信息的5种方式详解
JS基础:输出信息的5种方式详解
72 1
|
5月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
55 3
|
6月前
|
前端开发 数据安全/隐私保护
crypto-js中AES的加解密封装
文章介绍了如何在前端使用crypto-js库进行AES加密和解密,提供了加解密的函数封装示例,并演示了如何加密和解密字符串或对象。
440 1
crypto-js中AES的加解密封装
|
6月前
|
设计模式 JavaScript
JS发布订阅模式封装(纯手工)
发布订阅模式是JS常用的设计模式,在面试中也会经常遇到,以下是我的手写实现方式,经测试效果不错,小伙伴们们可以直接拷贝使用。

热门文章

最新文章