天天看點

JS讀書筆記(一)面向對象

面向對象

 面向對象的三大特點:封裝、繼承、多态

javascript語言本身擁有對象,實作了對屬性,方法的封裝(也隻是封裝了一半,并沒有實作對屬性和方法的通路控制),卻并沒有實作繼承和多态,但卻利用語言的其他特性實作(具體哪些特性,有待研究)了(曲線救國)了繼承和多态。是以個人認為javascript”算是“面向象對象語言(重點于寫代碼的人有沒有面向對象的思想)。

  1. 利用javascript函數的”閉包“特征,可以實作”封裝“特點——對屬性的公有和私有控制
    function List(){
      //利用閉包實作私有屬性
      var m_elements = [];
      
      m_elements = Array.apply(m_elements, arguments);
      //公有屬性  
      this.length = {
    	  valueOf:function(){
    		    return m_elements.length;
          },
          toString:function(){
    			return m_elements.length;
    	  }
      }
      //公有方法  
      this.toString = function(){
        return m_elements.toString();
      }
      
      this.add = function(){
         
    	 m_elements.push.apply(m_elements,arguments);  
      }
    }
    
    var alist = new List(1,2,3);
    alert(alist); //相當于 alist.toString();
    alert(alist.length)//相當于 alist.length.toString();      

在javascript裡,對象的屬性和方法支援4種不同的的類型:

  • 私有屬性
  • 動态公有屬性
  • 靜态公有屬性(原型屬性)
  • 類屬性
function myClass(){
  //私有變量
  var p = 100;
  //動态公有變量
  this.x = 10;
}
//靜态公有變量(原型屬性),一旦改動,将影響所有對象,所有對象都可以通路
myClass.prototype.y = 20;
//類變量
myClass.z = 30;

var a = new myClass();

a.p // undefined   因為是私有變量是以該問不到
a.x = 20; // 改變動态公有變量
a.y = 40; // 給單個執行個體a添加動态公有變量,與原型屬性重複時,将覆寫原型屬性
delete(a.x); //删除動态公有變量x
delete(a.y); //删除動态公有變量y
a.x // undefined a沒了,自然沒法通路
a.y // 20 原型屬性又還原了,哈哈
myClass.z //30,沒啥好說的      

匿名函數最有趣的用途是用來建立閉包。閉包(closure)是一個受到保護的變量空間,由内嵌函數生成。Javascript具有函數級的作用域。這意味着定義在函數内部的變量在函數外部不能被通路。Javascript的作用域又是詞法性質(lexicallly scoped)。這意味着函數運作在定義它的作用域中,而不是在調用它的作用域中。把兩個因素結合起來,就能通過把變量包裹在匿名函數中而對其加以保護。

                                                                                                                                 ---《javascript設計模式》

對象的易變性:可以動态的修改類或對象。

對象的内省性:即反射機制(reflection)。

JS在模仿傳統的面向對象特性的技術都依賴于對象的易變性和反射機制。

對象易變性的缺點:随時都可以修改一個類或對象,這使得一個對象/類的特征不穩定,進行類型檢查很困難,是以這是JS缺少類型檢查的原因之一。

繼承:JS的繼承是基于對象的(原型式)繼承,它可以用來模仿基于類(類式)繼承。這兩種繼承方式的性能也會不同,根據手頭任務的實際情況,有時其中的某種會更适合一些。

繼續閱讀