博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js闭包应用
阅读量:5973 次
发布时间:2019-06-19

本文共 3942 字,大约阅读时间需要 13 分钟。

 

先来看一个例子:

function foo() {      var a = 10;           function bar() {        a *= 2;        return a;      }             return bar;          }    var baz = foo(); // baz is now a reference to function bar.    console.log(baz()); // returns 20.    console.log(baz()); // returns 40.    console.log(baz()); // returns 80.    var blat = foo(); // blat is another reference to bar.    console.log(blat()); // returns 20, because a new copy of a is being used.

一直以来,我都是以为只有用匿名函数才能算是闭包,但是其实不一定要用匿名函数的,就是一般的函数就可以,前提是它得被包含在另一个函数中。

在foo返回后,它的作用域被保存下来了,但只有它返回的的那个函数能够访问这个作用域。在前面的示例中,baz和balt各有各的作用域及a的一个副本,而且只有他们自己能对其进行修改。

其实就是说我们对foo函数的引用的调用并不会对其他引用有任何影响。

 

二、封装和隐藏信息

看了上面的例子,我们可以考虑采用匿名函数来进行封装和隐藏私有变量。

 

var Book = function(newIsbn, newTitle, newAuthor) { // implements Publication  // Private attributes.  var isbn, title, author;  // Private method.  function checkIsbn(isbn) {    //...     return true;  }    // 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';  };  // Constructor code.  this.setIsbn(newIsbn);  this.setTitle(newTitle);  this.setAuthor(newAuthor);};// Public, non-privileged methods.Book.prototype = {  display: function() {    //...  }};var mybook=new Book("myisbtn","mytittle","myauthor");console.log(mybook.getAuthor());
View Code

 

我们通过在构造器中用var声明了这些变量和checkIsbn函数,因此他们就变成了私有的属性。需要访问这些变量和函数的方法只需要在Book中声明即可。这些方法也被陈伟特权方法。而任何不需要访问私有属性的方法都要在Book.prototype中声明。例如display。但这里也存在个问题:就是每生成一个新的对象实例都将为每一个私有方法和特权方法生成一个新的副本。这会比其他做法耗费更多内存,因此只宜用在真正需要私有成员的场合。另外,这种模式也不适合派生子类,因为派生的子类并不能访问超类的任何私有属性和方法。故在JavaScript中用闭包实现私有成员导致派生问题被称为“继承破坏封装”。

 

三、改进

这里与上一种大体类似,但是也有一些重要的区别。这里私有成员和特权成员仍被声明在构造器中,但是构造器已经变成一个内嵌函数了,并且被作为包含它的函数的返回值赋给变量Book.这就是创建了一个闭包,你可以把静态的私有成员函数声明在里面。

checkIsbn函数被设置为静态方法,是因为没必要为每个实例都生成这个方法的一个副本。此外还有静态属性numBooks限制了构造器总的调用次数

var Book = (function() {    // Private static attributes.  var numOfBooks = 0;  // Private static method.  function checkIsbn(isbn) {   // ...   return true;   }      // 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';    };    // Constructor code.    numOfBooks++; // Keep track of how many Books have been instantiated                  // with the private static attribute.    if(numOfBooks > 1) throw new Error('Book: Only 1 instances of Book can be '        + 'created.');    this.setIsbn(newIsbn);    this.setTitle(newTitle);    this.setAuthor(newAuthor);  }})();// Public static method.Book.convertToTitleCase = function(inputString) {  //...  console.log("convertToTitleCase");};// Public, non-privileged methods.Book.prototype = {  display: function() {    //...    console.log("display");  }};var mybook=new Book("myisbtn","mytittle","myauthor");console.log(mybook.getAuthor());    //myauthormybook.display();                   //display//mybook.convertToTitleCase();      //mybook.convertToTitleCase is not a functionvar mybook2= new Book("my2","tittle2","myauthor2");console.log(mybook2.getAuthor());   //Only 1 instances of Book can be created.
View Code

 

转载地址:http://pmbox.baihongyu.com/

你可能感兴趣的文章
JSP页面获取系统时间
查看>>
L-1-19 Linux之RAID&分区&文件系统命令
查看>>
stat查找权限以数字形式显示
查看>>
Java面向对象学习笔记(二)
查看>>
源码编译安装httpd2.4.9
查看>>
linux系统优化
查看>>
在使用 Windows Update 检查更新时,系统没有提供下载 Windows 7 SP1 的选项
查看>>
CSS控制XML与通过js解析xml然后通过html显示xml中的数据
查看>>
在Struts + Spring + Hibernate的组合框架模式中,三者各自的特点都是什么
查看>>
Windows 2012 R2 DataCenter服务器DNS无法打开AD, DNS错误代码4000 4007 4013
查看>>
网络学习(二十一)创建用户及文件夹共享设置的简单应用
查看>>
java基础数据类型char
查看>>
打印 PE导入导出表
查看>>
miniWindbg 功能
查看>>
五、判断银行卡号的正则
查看>>
mysql基于mysqlslap的压力测试
查看>>
zencart中query_factory.php中连接mysql次数
查看>>
fail2ban 保护linux安全(转载)已用于生产环境
查看>>
if,for,while,case,break,continue,exit
查看>>
表格元素的添加和删除,计算器,全选全不反选
查看>>