javascript語言精粹----筆記

1.6種值會爲假(==false),分別是false,null,undefined,' ',0,NaN
2.typeof有6種值,分別是'number','string','boolean','undefined','function','object';其中typeof(null),結果是'object'
3.number類型總是64位浮點數,兩個整數相除也可能出現非整數結果
4.如果第一個運算數的值爲假,那麼運算符&&產生它的第一個運算數的值.否則,它產生第二個運算數的值.如,可利用&&運算符避免檢索undefined引起的異常
flight.equipment                                             //undefined
flight.equipment.model                                   //throw"TypeError"
flight.equipment && flight.equipment.model     //undefined
5.如果第一個運算數的值爲真,那麼運算符||產生它的第一個運算數的值.否則,它產生第二個運算數的值.如,可利用||運算符來填充默認值
          var status = flight.status || "unkonwn"
6.對象通過引用來傳遞,永遠不會被拷貝
7.當我們對某個對象的屬性做出改變時,不會觸及到該對象的原型.原型鏈只有在檢索值得時候,纔會自下至上,直到object.prototype中去尋找,找到就用,然後停止尋找,都沒有就返回undefined,這個過程稱爲委託.hasOwnProperty方法可以檢測對象擁有的獨特屬性.
8.通過for in語句迭代出的對象屬性包含其原型鏈上的屬性,且無序;而通過for語句根據對象的length循環出的屬性,只包含獨有屬性,且順序
9.delete可以刪除對象的屬性,不會觸及對象原型上的屬性
10.函數也是對象,對象字面量產生的對象擁有到Object.prototype的隱藏鏈接,函數對象擁有到Function.prototype(該原型對象本身鏈接到Object.prototype)的隱藏鏈接.每個函數對象在創建時也隨帶一個prototype屬性,它的值是一個擁有constructor屬性且值即爲該函數的對象
11.每個函數在創建時附有兩個附加的隱藏屬性:函數的上下文(可調用)和實現函數行爲的代碼;調用一個函數將暫停當前執行,傳遞控制權和參數給新函數.除了聲明時定義的形參,每個函數接收兩個附加的參數:this和arguments,arguments.callee代表函數自身,通常用於遞歸
12.參數this的值取決於調用的模式,javascript中一共有四種調用模式:
     方法調用模式:當一個函數被保存爲對象的一個屬性時,我們稱它爲一個方法,一個方法被調用時,this綁定到該對象(只要函數被調用的時候用一個.點或者[subscript]下標方式調用,那麼它被當做一個方法來調用)
     函數調用模式:當一個函數並非一個對象的屬性時,那麼它被當做一個函數來調用,this被綁定到全局對象;解決內部函數的this被指向全局的設計缺陷時,可以在外部var that=this;如在瀏覽器中,this = window;在node中,this = globe
     構造器調用模式:如果在一個函數前面帶上new來調用,那麼將創建一個隱藏鏈接到該函數的prototype成員的新對象,同時this將會被綁定到那個新對象上.
     apply調用模式:this綁定到第一個參數,即傳入對象
13.函數的實參(arguments)和型參(parameters)的個數不匹配時不會報錯;如果實參多了,超出的將被忽略.如果實參過少,缺少的會被傳入undefined.
14.arguments並不是一個真正的數組,它只是一個類似數組的對象,除了length屬性,它缺少其它數組方法.
14.5 一個函數總會返回一個值,沒有指定返回值,則返回undefined.如果函數以new方式調用,且返回值不是一個對象,則返回this(該新對象)
15.javascript缺少塊級作用域,所以,最好的做法是在函數體的頂部聲明函數中可能用到的變量
16.利用閉包來返回外部函數變量的方式,可以避免一個函數被加上new來使用
     閉包:var quo = function (status){
          return {
               get_status : function () {
                      return status ;
                    }
               };
              };
        var myQuo = quo ("amazed");
   構造函數:
        var Quo = function (status){
                this.status =status;
        };
        var myQuo = new Quo("amazed");
17. 一個閉包的坑
    var add_the_handles = function (nodes ) {
     var i;
    for(i = 0;i < nodes.length ; i+= 1) {
          nodes[i].onclick = function (e){
            alert(i);
          }
     }
};
add_the_handles 函數目的是給每個時間處理器一個唯一值(i).它未能達到目的是因爲事件處理器函數綁定了變量i,而不是函數在構造時的變量i的值.
改正爲以下寫法可達到目的:
    var add_the_handles = function (nodes ) {
     var i;
    for(i = 0;i < nodes.length ; i+= 1) {
          nodes[i].onclick = function (tempI){
            return function(e){
            alert(tempI);
          };
        }(i);
     }
};
18.回調
    模擬異步請求,避免客戶端被阻塞
   request = prepare_the_request();
  send_request_asynchronously(request,function(response){
        display(response);
};
19.模塊(module)通過函數和閉包來創建,只暴露可用的public方法,其它似有方法全部隱藏,如果你不需要傳參數或者沒有一些特殊苛刻的要求的話,我們可以在最後一個}後面加上一個括號,來達到自執行的目的,這樣該實例在內存中只會存在一份copy.可通過模塊模式來實現單例模式
var theModule = (function(){
       var i = 10;
       return {
          result :function(x) {
                 return x*i;
          }
      };
}());
調用:theModule.result(5);
20.通用遞歸記憶函數,加入一個記憶參數,可以減少遞歸函數的調用次數,顯著提高效率
var memoizer = function (memo,fundamental) {
      var  shell = function (n) {
         var result = memo[n];
        if(typeof result !== 'number') {
           result = fundamental(shell,n);
          memo[n] = result;
        }
      return result;
      };
      return shell;
};
調用:
 var fibonacci = memoizer([0,1],function(shell,n){
      return shell(n-1)+shell(n-2);
});
console.log(fibonacci(10));
21.當一個函數對象被創建時,Function構造器產生的函數對象會運行類似代碼: this.prototype = {constructor : this};所有的構造器函數都約定命名成爲字母大寫的形式,但更好的備選方案是不適用new
22.構造器函數要接受一大串參數的寫法:
   不建議寫法: var myObject = maker(f,l,m,c,s);
      建議寫法: var myObject = maker({
                first : f,
                last: l,
                state:s,
                city:c
           });
好處是多個參數可以任意排序,如果有默認值,可以忽略到一些參數,且代碼更易讀
23.在一個純粹的原型模式中,我們會摒棄類,轉而專注於對象,一個新對象可以繼承一個就對象的屬性
24.在僞類模式與模塊模式中,儘量選擇後者,函數化構造器僞代碼模板
  var constructor = function (spec ,my) {
     var that,其他的私有實例變量;
     my = my || {};
    把共享的變量和函數添加到my中
    that = 一個新對象
   添加給that的特權方法
    return that;
}
25.javascript的數組是一種擁有一些類數組特性的對象.它把數組的下標轉變成字符串,用其作爲屬性,比普通屬性多了一個可以用整數作爲屬性名的特性.且繼承自Array.prototype,多了一個length屬性;javascript同一個數組的元素可以是混合類型,且沒有上界.
26.  var numbers = ['zero','one','two'];
    numbers[numbers.length] = 'three';  等價於
   numbers.push('three');
27.是否數組檢測
 var is_array = function (value) {
    return value &&
   typeof value === 'object' &&
   typeof value.length === 'number' &&
  typeof value.splice === 'function' &&
 !(value.propertyIsEnumerable('length'));
};
28.javascript中的糟粕
全局變量        :越少越好
作用域           :無塊級作用域,在每個函數開頭部分聲明所有變量
自動插入分號  :因此大括號風格需使用埃及括號
Unicode        :javascript字符是16位的,只能覆蓋65535個字符
parseInt        :增加第二個參數,明確進制,parseInt("08",10)
浮點數           :二進制浮點數不能正確的處理十進制小數,0.1+0.2不等於0.3,不過整數部分是精確的
NaN              : typeof NaN === 'number'  //true;  NaN === NaN //false;
對象              :因爲原型鏈的存在,javascript對象永遠不會有真的空對象
29.javascript中的雞肋
運算符 ==和!= :會試圖強制轉化判斷值的類型,規則複雜
with語句          :可能出現歧義,並影響處理器速度
eval                :降低安全性,增加閱讀複雜性
continue          :重構移出continue後,性能得到改善
++ --              :使代碼變得更隱晦
位運算符           :javascript沒有整數類型,位操作符將它們的運算數先轉換成整數,接着執行運算,然後再轉化回去,非常慢
function           :不在if語句中使用function,儘量用var func = function... 的形式聲明
new                 :更好的應對策略是根本不去使用new
void                 :將返回undefined,沒有什麼用,而且讓人困惑
發佈了16 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章