最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS閉包原理與應用經(jīng)典示例

 更新時間:2018年12月20日 10:25:03   作者:huansky  
這篇文章主要介紹了JS閉包原理與應用,結合實例形式較為詳細的分析了javascript閉包的原理、應用及相關操作注意事項,需要的朋友可以參考下

本文實例講述了JS閉包原理與應用。分享給大家供大家參考,具體如下:

一、先來看一個例子:

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.

這里使用在線HTML/CSS/JavaScript代碼運行工具http://tools.jb51.net/code/HtmlJsRun測試上述代碼,可得到如下運行結果:

一直以來,我都是以為只有用匿名函數(shù)才能算是閉包,但是其實不一定要用匿名函數(shù)的,就是一般的函數(shù)就可以,前提是它得被包含在另一個函數(shù)中。

在foo返回后,它的作用域被保存下來了,但只有它返回的的那個函數(shù)能夠訪問這個作用域。在前面的示例中,baz和balt各有各的作用域及a的一個副本,而且只有他們自己能對其進行修改。

其實就是說我們對foo函數(shù)的引用的調用并不會對其他引用有任何影響。

二、封裝和隱藏信息

看了上面的例子,我們可以考慮采用匿名函數(shù)來進行封裝和隱藏私有變量。

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());

使用在線HTML/CSS/JavaScript代碼運行工具http://tools.jb51.net/code/HtmlJsRun測試上述代碼,可得到如下運行結果:

我們通過在構造器中用var聲明了這些變量和checkIsbn函數(shù),因此他們就變成了私有的屬性。需要訪問這些變量和函數(shù)的方法只需要在Book中聲明即可。這些方法也被陳偉特權方法。而任何不需要訪問私有屬性的方法都要在Book.prototype中聲明。例如display。但這里也存在個問題:就是每生成一個新的對象實例都將為每一個私有方法和特權方法生成一個新的副本。這會比其他做法耗費更多內(nèi)存,因此只宜用在真正需要私有成員的場合。另外,這種模式也不適合派生子類,因為派生的子類并不能訪問超類的任何私有屬性和方法。故在JavaScript中用閉包實現(xiàn)私有成員導致派生問題被稱為“繼承破壞封裝”。

三、改進

這里與上一種大體類似,但是也有一些重要的區(qū)別。這里私有成員和特權成員仍被聲明在構造器中,但是構造器已經(jīng)變成一個內(nèi)嵌函數(shù)了,并且被作為包含它的函數(shù)的返回值賦給變量Book.這就是創(chuàng)建了一個閉包,你可以把靜態(tài)的私有成員函數(shù)聲明在里面。

checkIsbn函數(shù)被設置為靜態(tài)方法,是因為沒必要為每個實例都生成這個方法的一個副本。此外還有靜態(tài)屬性numBooks限制了構造器總的調用次數(shù)

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());  //myauthor
mybook.display();          //display
//mybook.convertToTitleCase();   //mybook.convertToTitleCase is not a function
var mybook2= new Book("my2","tittle2","myauthor2");
console.log(mybook2.getAuthor());  //Only 1 instances of Book can be created.

使用在線HTML/CSS/JavaScript代碼運行工具http://tools.jb51.net/code/HtmlJsRun測試上述代碼,可得到如下運行結果:

更多關于JavaScript相關內(nèi)容感興趣的讀者可查看本站專題:《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數(shù)據(jù)結構與算法技巧總結》、《JavaScript遍歷算法與技巧總結》及《JavaScript數(shù)學運算用法總結

希望本文所述對大家JavaScript程序設計有所幫助。

相關文章

最新評論

都兰县| 枣强县| 通州区| 邛崃市| 广元市| 会同县| 沅江市| 城步| 高青县| 古田县| 亳州市| 泰和县| 晋中市| 马尔康县| 康定县| 萨嘎县| 巴东县| 德惠市| 麻栗坡县| 陆川县| 闸北区| 同仁县| 三门峡市| 偏关县| 安顺市| 修武县| 香河县| 筠连县| 云和县| 元阳县| 吉林省| 舞钢市| 扶绥县| 墨竹工卡县| 惠东县| 和硕县| 乌兰浩特市| 新兴县| 阿拉尔市| 大宁县| 托克托县|