《JavaScript語言精髓與編程實踐》讀書筆記--基礎篇

一、弱類型語言:
      JavaScript   是弱類型語言。但所謂言 弱類型語言 ,只代表該語言在表達式運 算中不強制校驗運算元的數據類型,而並不代表該語言是否具備類型系統。
二、 JavaScript 識別6 種數據類型,並在運算過程當中自動處理語言類型的轉換。
  2.1   6種數據類型:
      undefine、number、string、boolean、function、object, typeof   運算老是以字符串形式返回上述   6   種類型值之一。
  2.2   變量的兩種類型:
     1)基本類型在內存中具備固定的大小,而引用類型則不一樣。例如,對象能夠具備任意的長度,無固定大小。數組也是。
     2)基本類型變量存的是數據的具體值,而引用類型變量保存的是值的引用。   
      基本類型: undefine、number、boolean string
     引用類型: function、object
三、NaN 值:
      至少表面上來看, 一個值應該與其自身「 等值   / 全等」。但事實上,在 JavaScript   中存在一個例外:一個   NaN   值,與自身並不等值,也不全等。
四、 空字符串用做對象成員。
      JavaScript   中也能夠用一對不包含任意字符的單引號與雙引號來表示一 個空字符串(   Null String ),其長度值老是爲 0 。比較容易被忽視的是,空字符 串與其它字符串同樣也能夠用做對象成員。
object{
          '':100;
     }
 alert('');  //100
五、相等運算符 == 和等同運算符 === 。
     1) === 運算符是等同運算符,它採用嚴格的同一性定義檢測兩個運算數是否徹底等同。
     2)== 運算符是相等運算符,它採用比較寬鬆的同一性定義(即容許進行類型轉換)檢測兩個運算數是否相等。
下面的規則用於斷定   ===  運算符比較的兩個值是否徹底相等:
     1.若是兩個值的類型不一樣,它們就不相同。
     2.若是兩個值的類型是數字,並且值相同,那麼除非其中一個或者兩個都是NaN(這種狀況它們不是等同的),不然他們是等同的。值NaN永遠不會與其餘的任何值等同,包括它自身。
     3.若是兩個值都是字符串,並且在串中的同一位置上的字符徹底相同,那麼它們就徹底等同。若是字符串的長度或內容不一樣,它們就不是等同的。
     4.若是兩個值都是布爾值true,或者兩個值都是布爾值false,那麼它們等同。
     5.若是兩個值引用的是同一個對象,數組或函數,那麼它們徹底等同。若是它們引用的是不一樣的對象(數組或函數),它們就不徹底等同,即便這兩個對象具備徹底相同的屬性或兩個數組具備徹底相同的元素。
     6.若是兩個值都是null或都是undefined,它們徹底相同。

下面的規則用於斷定 ==運算符比較的兩個值是否相等:
     1.若是兩個值具備相同的類型,那麼就檢測它們的等同性。若是這兩個值徹底相同,它們就相等。若是它們不徹底相同,則它們不相等。
     2.若是兩個值的類型不一樣,它們仍然可能相等。用下面的規則和類型轉換來檢測它們的相等性:
        2.1 若是一個值是null,另外一個值是undefined,它們相等。
        2.2 若是一個值是數字,另外一個值是字符串,把字符串轉換爲數字,再用轉換後的值進行比較。
        2.3 若是一個值是true,將它轉換成1,再進行比較。若是一個值爲false,把它轉換成0,再進行比較。
        2.4 若是一個值是對象,另外一個值是數字或者字符串,將對象轉換成原始類型的值,再進行比較。
        2.5 其餘的數值組合是不相等的。
六、delete 運算符:
  6.1  delete   能夠刪除不少東西 ( 包括對象成員和數組元素   ) ,但它不能刪除:
      1) var   聲明的變量;
      2)直接繼承自原型的成員。
var obj = {
          method : function() { },
          prop : 1234
     }
     golbal_value  =  'abcd';
     array_value = [0,1,2,3,4];
     function testFunc() {
          value2 = 1234;
          delete value2;
     }
     // 調用testFunc() 函數,函數內部的delete 用法也是正確的
     testFunc();
     // 如下四種用法都是正確的
     delete obj.method;
     delete obj[ 'prop' ];
     delete array_value[ 2 ];
     delete golbal_value;

     delete 不能刪除繼承自原型的成員。但若是你修改了這個成員的值,你仍然能夠刪除它,這將使它恢復到原型的值。關於這一點的真相,是 delete 運算事實上是刪除了實例的成員表中的值。 數組

  6.2  delete   僅在刪除一個不能刪除的成員時,纔會返回   false   。其 它狀況下,例如刪除不存在的成員,或者繼承自父代類/原型的成員,都 將返回 true
function MyObject() {
     }
     MyObject.prototype.value = 100;
     // 該成員繼承自原型,且未被重寫, 刪除返回true.
     // 因爲delete 操做不對原型產生影響, 所以obj1.value 的值未變化.
     var obj1 = new MyObject();
     alert( delete obj1.value );
     alert( obj1.value );
     // 嘗試刪除Object.prototype ,該成員禁止刪除, 返回false
     alert( delete Object.prototype );
七、對象及其成員的檢查:
  7.1   in 運算。
  7.2  instanceof : insta nceof   將會檢測類的繼承關係。
// 聲明構造器
     function MyObject( ) {
     // ...
     }
     // 實例建立
     var obj = new MyObject( );
     // 顯示 true
     alert( obj  instanceof  MyObject );     
     function MyObjectEx( ) {
     // ...
     }
     //原型鏈
     MyObjectEx.prototype = new MyObject( );
     // 實例建立
     var obj2 = new MyObjectEx(  );
     // 檢測構造類, 顯示 true
     alert( obj2 instanceof MyObjectEx );
     // 檢測父類, 顯示 true
     alert( obj2 instanceof MyObject );
  7.3   propertyIsEnumerable  的一個實現版本, 該方法是不檢測對象的原型鏈的
    //code from Qomo Project.
    Object.prototype.propertyIsEnumerable = function(proName) {
          for ( var i in this ) {
               if ( i == proName ) break;
          }
          if ( i != proName ) return false;
          // if clone from prototype, return false.
          return this[ proName ] !== this.constructor.prototype[proName];
     }
      當某個對象成員不存在, 或它不可列舉時, 則對該成員調用 propertyIsEnumera ble() 方法將返回 false   —— 比較常見的狀況是,   JavaScript   象的內置成員是不能被列舉的。
var obj = new Object();
     // 不存在'aCustomMember', 顯示false
     alert( obj.propertyIsEnumerable('aCustomMember') );
     // 內置成員不能被列舉,這種狀況下,你能夠用  in 運算檢測到該成員,但不能用 for..in 語句來列舉它。
     alert( obj.propertyIsEnumerable( 'constructor' ) );
八、缺省對象的指定:with語句。
// 示例1: 存取對象成員
     var obj = new Object( );
      obj.value = 100;
     // 示例2: 訪問(全局的)對象或值
     value = 1000;
     with ( obj ) {
           value *= 2;
     }
     alert( obj.value );  //200
     alert( value );  //100
九、
//聲明對象直接量
     var obj = {
          v1: 1,
          v2: 2,
          v3: 3
     }
十、[ ] 的二義性: 數組聲明、 數組下標運算符、對象成員的存取運算符。
      a = [ [ ][ 100 ] ];  // 第一個數組爲空數組, 第二個數爲任意數值,都將獲得[ undefined ]
      a = [ [ 1, 2, 3 ][ 2 ] ]; // 第一個數組有三個元素,所以arr[2] 是存在的,故而獲得[ 3 ]
      a = [ [ ][ ] ];  // 第一個數組爲空,是正常的;但第二個做爲下標運算時缺乏索引,故語法錯
十一、語法做用域
     分表達式(一級)、語句、函數、全局四級
      1)語法做用域是互不相交的。正是做用域互不相交的特性構造了代碼結構化的層 次,並消除了一些錯誤隱患。
      2) 語法做用域間能夠存在平行或包含關係。 高級別能夠嵌套低級別的語法做用 域,反之則不成立。
      3)高級別的流程變動子句(或語句)能夠跨越低級別的做用域,反之則不行。
十一、變量做用域

     表達式級、函數(局部)級、全局,JavaScript 不存在語句級別的變量做用域。在全局範圍內使用 for 循環的同時聲明變量,該變量是全局變量。 函數

十二、因爲JavaScript 是動態語言,所以它只能依賴「變量做用域」來實現封裝特性。 this

1三、對象的多態性被轉換爲運行期的動態特性—— 例如咱們能夠動態地添加對象的方法/成員,使它看起來象是某個對象。
1四、類抄寫與原型繼承:
     1) 類抄寫時成員訪問效率更高,但內存佔用較大;而原型繼承反之。
     2) 類抄寫不依賴內部原型鏈來維護繼承關係,所以也不能經過   instanceof   來作這 種檢測;原型繼承卻能夠在   new   運算時維護這種繼承關係,也能夠檢測之。
1五、非惰性求值
/**
* 示例1:在參數中使用表達式時的求值規則
*/
var i = 100;
alert( i+=20, i*=2, 'value: '+i );  //120
alert( i );  //240
1六、callee
      JavaScript 1.2   開始使   arguments   對象擁有一個成員: callee ,該成員 老是指向該參數對象   (Arguments) 的建立者函數。因爲 arguments   老是在函數內 部能夠直接訪問,所以也就老是能夠在函數內部識別「我是誰」。
      這樣一來,不管是否匿名,函數的遞歸就老是能夠寫成:(callee 解決了匿名遞歸的問題
void function() {
     // ...(略)
     arguments.callee();
     }();
1七、caller  
    caller  Function  的一個成員,指向函數調用者。
1八、null是一個object實例(空對象),  typeof null的值是object。
相關文章
相關標籤/搜索