Java程式員的JavaScript學習筆記(4——閉包/getter/setter),gettersetter

來源:互聯網
上載者:User

Java程式員的JavaScript學習筆記(4——閉包/getter/setter),gettersetter

計劃按如下順序完成這篇筆記:

這是筆記的第4篇,聊聊閉包/getter/setter,看看JavaScript中的變數範圍和實現封裝的方法。

1、閉包

閉包是JavaScript一項簡單實用的語言特性。通過閉包:
彌補了函數沒有public/private等訪問存取權限控制符的缺陷,保護了函數內部變數的安全。
使得函數對象在作為參數傳遞時,不僅僅傳遞運算邏輯,同時也傳遞了相關變數。
使得函數“類”的不同執行個體,獨享自己的屬性。
下面逐個來看。

1.1、保護私人變數1.1.1、原理

閉包最主要的特性是:當函數作為返回值時,連同函數定義時的環境(包括函數外部,函數可以訪問到的變數)一起返回,確保這些變數不因其依附的對象銷毀而被銷毀。
有點兒繞,具體什麼意思呢?看下面的代碼:
// 程式碼片段1
 function UiObject() {
     var childCount = 0; // 函數內部變數,  
     return 0;
 }
 
 var funcReturnValue = UiObject();  // 調用函數,返回0
 console.log(UiObject.childCount);   // 輸出:undefined,由於函數調用完成,內部變數已經被銷毀
 
 childCount隨著UiObject函數的調用結束而銷毀,從另一個角度看,保護了函數內部的變數。
 在這個基礎上,如果我們有一種辦法可以確保函數的內部變數不被銷毀,而且提供方法對其訪問操作,也就實現了通過public方法訪問 private 變數。
 代碼如下:
 // 程式碼片段2
 function UiObject() {
     var childCount = 0; // 函數內部變數
     function getChildCount(){
         childCount = 6;
         return childCount;
     }
     return getChildCount;
 }
 var funcReturnFObject = UiObject();  // 調用函數,返回 getChildCount 函數,返回值是一個閉包
 console.log(funcReturnFObject());   // 輸出:6
 下面我們就看看,如果利用閉包的這一特性實現對私人屬性的保護。
 
 

 1.1.2、文法

 在程式碼片段2的基礎上改進,程式碼片段3展示的代碼,可以同時提供多個方法,對私人屬性訪問。
 //程式碼片段3
 function UiObject() {
     var childCount = 0; // 函數內部變數
     
     return {
         getChildCount : function (){
             return childCount;
         },
         setChildCount : function (cnt){
             childCount = cnt;
         }
     };
 }
 
 var o = UiObject();  // 調用函數,返回 getChildCount 函數,返回值是一個閉包
 o.setChildCount(6);
 console.log(o.getChildCount());   // 輸出:6
 
 思考: 如果 var childCount = 0 ; 改為 this.childCount = 0; 呢?
 我們之前研究過this,“ this.childCount = 0; ”語句是將childCount附加為調用者的屬性,this.childCount的將生命週期與調用者相同。這與閉包不衝突。
 
 程式碼片段3還可以寫成程式碼片段4的形式。
 
 // 程式碼片段4
 function UiObject() {
     var childCount =  0; // 函數內部變數
     this.setChildCount = function(cnt){
         childCount = cnt;
     };
     this.getChildCount = function(){
         return childCount;
     };
 }
 
 var ui = new  UiObject();          // 調用函數,返回retObj
 console.log(ui.childCount);       // 輸出:undefined,由於函數調用完成,局部變數已經被銷毀
 ui.setChildCount(3);                  // 由於閉包的作用,ui仍然儲存著變數childCount,並對其操作
 console.log(ui.getChildCount()); // 輸出:3
 
 “this.setChildCount = function(cnt){       childCount = cnt;   };” 這個語句相當於在UiObject內部定義了函數並“傳遞”了給ui對象。同樣產生了閉包。
 

1.2、傳遞函數時,同時傳遞上下文

通過上面的例子,我們已經看到了這點特性。
在具體的應用情境中可對其大加利用。

1.3、不同執行個體,獨享自己的變數

我們已經知道了,函數在傳遞過程中,會產生一個閉包。對於同一方法產生的閉包,是相同的,還是為每次傳遞建立了不同的拷貝呢?
看下面的代碼:
//程式碼片段5
 function UiObject() {
     var childCount = 0; // 函數內部變數
     
     return {
         getChildCount : function (){
             return childCount;
         },
         setChildCount : function (cnt){
             childCount = cnt;
         }
     };
 }
 
 var ui1 = UiObject();
 var ui2 = UiObject();
 
 ui1.setChildCount(1);
 ui2.setChildCount(2);
 
 console.log(ui1.getChildCount()); // output : 1
 console.log(ui2.getChildCount()); // output : 2
 
 每次產生閉包是不同的拷貝。
 
 思考:對比Java,加深理解。
 
 

2、getter/setter


JavaScript
 //程式碼片段6
 var uiPanel ={
     _type  : 'Panel',
     _width : -1,
     _height: -1,
     
     get type(){ return this._type;},
     
     get width(){ return this._width; },
     set width(v){this._width = v;},
     
     get height(){ return this._height; },
     set height(v){this._height = v;}
 };
 
uiPanel.type = 'TextField';          // does not work
console.log('type:'+uiPanel.type); // ouput :         type:Panel
 
 uiPanel.width = 800;                 //
 console.log('width:'+uiPanel.width); // ouput :         width:800

文法上越發有物件導向的範兒了。
除了在定義時通過set/set關鍵字控制屬性的讀寫權限。還可以在運行期通過 Object.defineProperty()函數動態添加屬性,並提供更精細的控制。
代碼如下(以下代碼均未經實驗):
var o = {};
Object.defineProperty(o,'propName',{
            value:1,  //屬性的值,也可以通過   get:function(){retun x;}的方法設定
            writeable:true,//是否可以通過o.propName  = newValue ; 的方法設定屬性的值
            enumerable:false,//是否可以通過被枚舉
            configurable:true//是否可以通過defineProperty配置
    });
另外,還有一系列API可以完成對屬性的配置、檢測。如下:
Object.getOwnPropertyDescriptor{{x:1},"x"}
Object.keys(obj);    // 獲得對象上所有可枚舉的“執行個體屬性”
Object.getOwnPropertyNames(obj) ;//獲得對象上所有的“執行個體屬性”
obj.hasOwnProperty(‘id’); //只要該對象obj擁有屬性id, 無論id是否可枚舉,都返回true


3、小結

當大多數人已經習慣了物件導向的思維和方法,語言就要從特性方面予以滿足,這不合理,也不美。但世界就是如此不完美。

JavsScript天生麗質,非要把她改造成機甲戰士,那以後誰來負責傾國傾城呢?

ECMAScript 5不是革命性創新,也不是救命稻草,這個世界本來可以更好的。





JAVA中的setter//getter()方法是什?

用代碼講解一下:
public class Student {
String name;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s1=new Student();
s1.setName("小明");
System.out.println("學生的姓名為:"+s1.getName());
}
}

上面的意思是建立一個學生類,聲明一個name變數,並給了它getter和setter方法。
先說setter方法,剛開始建立name變數時沒有賦值,後面用這個方法給他賦值“小明”
再說getter方法,name變數有了值“小明”後就可以用這個方法把它調出來。
 
JAVA程式員需要學習那些課程

多思考 多看老員工的例子 遵守一些編碼規範 包括書寫以及架構規範
學習的知識太多了 javase(java核心技術) jsp(jsp2.0技術手冊) servlet struts(struts in action) spring(spring開發指南)
-----------------------------------------------
我就跟你在這裡說工作上能用的呢。首先你JavaSE的基礎要會,jsp要會寫,並且看得懂,EL最好可以寫一些,jstl基本上我們是不用的,因為有Struts。servlet要求多一點,因為Struts就是Jsp+Servlet的一個進階應用程式。然後你可以學學架構。Struts的結構瞭解就可以,運行以及載入過程要知道,並且在心裡有個數,Spring也一樣,hibrnate一般我們不用,因為項目太大的話優勢體現不出來,小的還可以。練習編寫代碼嚴格按照MVC的規範,嚴禁下層調用上層方法或屬性。在公司我們看的參考書也就是我說的那麼幾本。如果可以ajax最好懂得一些,會很有用。其實在我看來初級的知識就是JavaSE的知識,進階的那些也高不到哪裡去。每個公司都有自己的規範與方法,設計能輪到你就上,輪不到你你就老老實實的寫,設計模式在你參與設計的時候用的上。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.