《javascript權威指南》讀書筆記 -part2


我真的很佩服副院長~他是一個很有耐心 極其細致的人

工作態度嚴謹  代碼簡潔風格統一~再亂遭遭的代碼只要經過他的手就會變的很漂亮

羡煞我也~

不說廢話了  還是乖乖看書吧~maybe可能也許的某一天 我也可以。。。咕~~(╯﹏╰)b還是別做白日夢了 

 --------------part2--------------------------------------------------------------------------------------------------------

注釋:ECMA5-ECMAScript5
在開始之前,先講一下關於變量的知識:

好的習慣1:把所有的變量聲明放置在函數的開頭是一個好的編程習慣

還有一個很重要的概念~不可變的原始值和可變的對象引用(基本類型和引用類型

javascript中的原始值:undefined null boolean  string number   原始值是不可修改的。只有他們的值相等時他們才會相等。

引用類型:對象(包括數組和函數)  他們的值是可以修改的。對象的比較均是引用的比較,當且僅當他們引用同一個基對象時,他們才相等。

這就是為什么在工作中碰到一個問題~就是我明明沒有對一個數組進行操作,為什么最后它的值卻改變了

記住這一句話:變量保存了基本類型的實際值,而對於引用類型只保存對它的引用值。

eg:基本類型(數值  布爾值,null和undefined)
        var a=1;
        var b=a;
        var a = 3.14;
        alert(b)                    b = 1

        引用類型(對象,數組和函數)
        var  a =[1,2,3]
        var b =a;
        a[0] = 99;
         alert(b)                   b = [99,2,3]
View Code

 

先了解下typeof運算符:

   x                                        typeof x
undefined                                 "undefined"
null                                      "object"
true/false                                "boolean"
任意數字或NaN                              "number"
任意字符串                                 "string"
任意函數                                   "function"
任意內置對象(非函數)                        "object"

 

 對象

  除了字符串、數字、true、false、null和undefined之外,javascript中的值都是對象,盡管,最常見的用法是創建,設置,查找, 刪除,檢測和枚舉。

  1:對象的創建

    可以通過對象直接量,關鍵字new和ECMA5中的object.creat()創建對象。

    我想前面2個大家都很熟悉,對於第3個的方式首先解釋下原型。這也是我很薄弱但是確又是很重要的知識點(\(^o^)/~我要開始啰嗦了哈)。

    每個Javascript對象(null除外)都和一個對象相關聯。“另一個”對象就是我們熟知的原型,每一個對象都從原型繼承屬性。

    現在我們來分析下~

    對象直接量創建對象都具有同一個原型-object.prototype

    通過關鍵字new和構造函數調用創建的對象的原型就是構造函數的prototype屬性的值。

    沒有原型的對象為數不多,object.prototype就是其中之一。他不繼承任何屬性。其他的對象的原型都是普通對象,普通對象都具有原型。所有的內置構造函數(以及大部分自定義的構造函數)都具有一個繼承自object.prototype的原型。

    eg,Date.prototype的屬性繼承自object.prototype。這一系列鏈接的原型對象就是所謂的“原型鏈”

    object.creat({x:1;y:2})它創建了一個對象,第一個參數是這個對象的原型。

    object.creat({object.prototype});      //他和{}和new object()一樣

    object.creat()他實現了“可以使任意對象可繼承”,這是一個強大的特性。此方法是ECMA5才有,那ECMA3如何去實現呢?  

eg:通過原型繼承創建一個新的對象
function inherit(p){
  if(p == null)   throw TypeError();
  if(object.create)
      return object.creat(p);
  var t = typeof p;
  if(p!=="object" && p!== "function")
    throw TypeError()
 function f(){}
 f.prototype = p;
 return new f(); //返回一個新的對象 它是原型是p
}
inherit()函數的其中一個用途就是防止庫函數無意間(非惡意的)修改那些不受你控制的對象
var o={x:"donit change this value"};
library_function(inherit(0));

   2:對象的查詢及設置

    對像的查詢還有設置可以用a.name 或者a[name].

    注意只有在查詢屬性時才會體會到繼承的存在而設置屬性則和繼承無關。

    屬性訪問錯誤:當查詢對象一個不存在的屬性時不會報錯,o.x返回undefined;但是查詢不存在對象的屬性時就會報錯,o.x.length(null,undefined沒有屬性)

    可以用更簡練的方法  var len = book&&book.x&&book.x.length;

  3:刪除屬性

     delete運算符可以只能刪除對象可枚舉的自有屬性。

    注意delete只是斷開屬性和宿主對象的聯系,而不會去操作屬性中的屬性。

    eg:a={b:{c:1}};var t = a.b;delete a.b;consolse.log({"x":t.c}) //{x:1}

    由於已經刪除的屬性的引用依然存在,所以t.c的值還是1,所以在銷毀對象的時候,要遍歷屬性中的屬性,依次刪除。否則會造成內存泄漏。

  4:檢測屬性

    in:"x" in o; 檢測自有屬性和繼承屬性

    hasOwnProperty:o.hasOwnProperty("x")  檢測自有屬性

    propertyIsEnumberable():o.propertyIsEnumberable("x")  他是hasOwnProperty的增強版,檢測可枚舉的自有屬性時返回true。

                  某些內置屬性是不可枚舉的,通常由javascript代碼創建的屬性都是可枚舉的,除非在ECMA5中使用一個特殊的方法來改變屬性的可枚舉性。

    還有一種更簡單的 o.x!==undefined;if(o.x) o.x *=2;

  5:枚舉屬性

    for/in:遍歷對象中可枚舉的自有屬性和繼承屬性。對象繼承的內置對象是不可枚舉的。

    要獲取一個對象的自有屬性經常這個樣子

    for(prop in p){

      if(p.hasOwnProperty(prop)){

        .....

      }

    }

  6:屬性setter和getter

    對象屬性是由名字,值和一組特性(attribute)構成的。在ECMA5中,屬性值可以用一個或兩個方法替代,就是getter和setter。

    由getter和setter定義的屬性稱做“存取器屬性”,它不同於”數據屬性“,數據屬性只有一個簡單的值。

    當程序查詢存取器屬性時,調用getter方法。設置一個存取器屬性的值時,調用setter方法。

    和數據屬性不同,存取器屬性不具有可寫性。如果屬性同時具有getter和setter,那么他是一個讀/寫屬性。如果他只有getter方法,那么它是一個只讀屬性。如果它只有setter方法,那么它是一個只寫屬性,讀取只寫屬性總是返回Unedfined.

    和數據屬性相同的是存取器屬性時可以繼承的。

    eg:var o = {

        x:value,

        get access(){/*函數體*/},

        set access(){/*函數體*/}      

      };

  7:屬性的特性

    所有通過ECMA3的程序創建的屬性都是可寫的,可枚舉的和可配置的,且無法對這些特性做修改的。

    但是ECMA5是可以查詢和設置這些屬性特性的API,這些API對於庫的開發者來說是非常重要的:

      * 可以通過這些API給原型對象添加方法,並將它們設置成不可枚舉的,這讓它們看起來更像內置方法

      *   可以通過這些API給對象定義不能修改或刪除的屬性,借此"鎖定"這個對象。

    屬性包含一個名字和4個特性。數據屬性的4個特性是值(value)、可寫性(writable)、可枚舉性(enumberable)和可配置性(configurable)。

    存取器屬性的4個特性是讀取(get)、寫入(set)、可枚舉性和可配置性。

    為了實現屬性特性的查詢和設置操作,ECMA5定義了一個“屬性描述符”的對象

    object.getOwnPropertyDescriptor({x:1},x):獲取某個對象特定屬性的屬性描述符,稚嫩而過得到自有屬性的描述符。要想獲得繼承屬性的特性,需要遍歷原型鏈(object.getPrototypeOf())

    var o ={};     

    object.defineProperty(o,"x",{value:1,writable:true,enumerable:false,configurable:true});o.x;//1  object.keys(o);//[]

    這個方法要么修改已有屬性要么新建自有屬性,但不能修改繼承屬性。

    object.defineProperties():同時修改或創建多個屬性

    這個我就不在深入討論了~細節問題請看Page136

  7:對象的三個屬性

    每個對象都有與之相關聯的原型(prototype),類(class)和可擴展性(extensible)。這些屬性有什么作用呢,以及如何去查詢和設置他們呢?

    原型屬性:在實例對象創建之初就是設置好的~這個我就不繼續多說了。

         在ECMA5中,Object.getPrototypeOf()可以查詢他的原型鏈,ECMA3中滅有等價的函數,可以用o.constructor.prototype來檢測一個對象的原型,這種方式並不可靠,請參考后面的內容“類和模塊”的講解。

          isPrototype():檢測一個對象是否是另一個對象的原型(或處於原型鏈中)

          instanceof :判斷一個對象是否是一個類的實例。

                var d= new Date();

                d.instanceof Date; //true

                d.instanceof Object; //true 

    類屬性:對象的類屬性是一個字符串,用以表示對象的類型信息。Page140

    可擴展性:對象的可擴展性用以表示是否可以給對像添加新屬性。對象的可擴展性通常和屬性的可配置行與可寫性配合使用  

  8:序列化對象

    對象序列化是指將對象的狀態轉化為字符串,也可將字符串轉化成對象。只能序列化對象可枚舉的自有屬性。對於一個不能序列化的屬性倆說,在序列化的輸出字符串中會將這個屬性省略掉。

    ECMA5中提供了JSON.stringify()和JSON.parse()用來序列化和還原

    ECMA3中可以通過引入json2.js模塊來使用ECMAScript5中的這些函數

  9:toString()方法

    默認的toString方法的返回值帶有的信息量很少,因此很多類都帶有自定義的toString().eg:Array.toString(),Date.toString()以及Function.toString();

  10:valueOf()

    跟toString方法類似,轉化為數字的時候用這個方法,返回值帶有的信息量很少,因此很多類都帶有自定義的valueOf().

 

 

    

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM