《Javascript語言精粹》的學習(一).對象和函數

來源:互聯網
上載者:User

標籤:

最近在學習小馬和秦歌翻譯的《javascript語言精粹》,果然如傳聞般,裡面的內容博大精深。有些章節所表達的意思往往需要看到後面的章節內容時才能夠突然頓悟,因此,稱這本書需要反覆的去研究,真的名副其實。這兩天看了對象和函數這兩章,在這裡把自己覺得需要關注的內容做一下筆記:

 

①對象常量中屬性名稱的命名規範

記得剛開始學習對象常量的時候,覺得它真的很簡便。一個對象名,一個大括弧,N個“名/值”對,OK,搞定!可是在學習的過程中,也遇到過一些疑惑,比如在一些JS書籍中,在寫對象常量時,對象中有的屬性名稱用引號引起,有的屬性名稱卻沒有引號,比如以下的對象常量:

var flight={ airline:"Oceannic", first_name:"li", “first-name”:"hu"}

這應該是比較熟悉的對象常量。可是為何first_name沒有引號,而first-name卻需要引號呢。以前看過的JS書籍都沒有過解釋,而我也習慣在寫對象常量時,將所有的屬性名稱都用引號括住。在本書中,終於給出了詳細解釋。在對象字面量中,如果屬性名稱是一個合法的javascript標識符(標識符為首字母為單詞,後面選擇性加上一個或多個字母,數字或底線組成)且不是保留字,那麼屬性名稱可以不加上引號,初次之外,屬性名稱必須加上引號。本例匯總,first_name和airline是合法的標識符,而first-name不是標識符,所以必須加上引號。

②關於原型

我們都知道,JS的繼承方式並不是傳統的物件導向,而是面向原型繼承的。因此,在JS中,每個對象都會串連到一個原型對象,並從中繼承屬性。而對象字面量串連到Object.prototype中。這裡要注意的是,原型串連在更新時是不起作用的,只有在檢索值的時候才會起作用。更新時不起作用就是說對象只能改變它自身包含的屬性,而無法改變它串連到的原型鏈中的屬性。檢索時起作用是值當對象檢索某個屬性時,先檢查自身有沒有該屬性,如果沒有,再檢索它串連到的原型對象,如果原型對象中也沒有,再繼續檢索原型對象的原型對象,也就是順著原型鏈尋找。

 

③函數定義中形參的初始化

我們知道,函數的定義通常包括四部分,function,函數名(匿名函數可以省略),形參,花括弧。但是JS引擎如何初始化形參的呢。我們知道,在解析函數時,JS一般分為兩步:

第一是通過文法分析和預解析構建文法分析樹

第二是執行函數,在執行每個函數時會為該函數建立具體的執行環境和使用中的物件。

具體可見我轉載的一篇博文文法範圍與詞法範圍。我這裡要講的是,普通的變數在構建文法分析樹時就會被初始化,這時它們初始化為undefined(全域變數除外,全域變數直接初始化為它們所賦的值),而函數中的形參卻只有在函數調用時才會被初始化為實際提供的參數值。

④蛋疼的this

我們知道,函數既可以當作一個對象的方法來調用,也可以獨立調用。當它作為一個對象的方法時,顯而易見,它指向的是調用它的對象。但是當它獨立調用呢?給出一個例子:

 

   var flight={     airline:"Oceanic",     number:815,     ‘first-name‘:‘hu‘,     departure:{       IATA:"SYD",       time:"2004-09-22 14:25",       city:"Sydney"     }   }   flight.double=function(){     var that=this;     var helper=function(){        alert(that==this);     }     helper();   }   flight.double();

首先我把外層函數的this賦給that,然後在內層函數中將this關鍵字與that做全等號比較,結果彈出一個打打的false!蛋疼,內層函數中this並沒有綁定到外層函數的this,那麼它綁定的是什麼呢?好,修改一下代碼:

   flight.double=function(){     var that=this;     var helper=function(){        alert(window==this);     }     helper();   }   flight.double();

將this與window做全等,這時候再運行,發現彈出的是true。由此得出結論,當函數獨立調用時(這裡所屬的獨立是它既不屬於對象的方法,也不是用new來調用),它綁定到的是全域對象。這時候,為了使用外層函數中的this,例子中已經示範,可以在外層函數範圍中定義一個that變數,然後將this的引用賦給它,在內層函數中,可以使用that來訪問。

 

⑤偉大的閉包

習慣上,我們這樣去定義一個對象常量:

var myObject={ value:0, increment:function(inc){    this.value+=typeof inc===‘number‘?inc:1; }}

這是一個很簡單的定義。可是哪裡似乎有些問題!!不錯,安全性,某些時候,我值需要通過increment函數去修改value值,可是,如果這樣定義的話,貌似value可以隨便更改(myObject.value),這完全違反了我們的初衷,那麼該如何修改呢?不錯,利用閉包。

var myObject=function(){  var value=0;  return{     increment=function(inc){        value+=typeof inc===‘number‘?inc:1‘     }     getValue:function(){        return value;     }  }}();

大家再看,這時候,value的值可以如上例中隨便更改呢,檔案當然是否定的。函數範圍使它只對返回對象中的兩個方法可用,對其它程式是停用。唉,而myObject的值也不是一個函數,而是匿名函數調用後返回的閉包。唉,閉包真的是偉大!

 

⑥級聯

有用過jquery的童鞋應該知道,為何一個JQUERY對象可以在一條語句中調用那麼多的方法呢。不錯,用到的正是級聯。那麼級聯的原理是什麼呢?我們知道,有一些方法操作型的方法並沒有任何傳回值,這時候,這些方法返回的undefined,如果我們稍微設定一下,讓這些不需要傳回值的方法去返回this呢,也就是說在這些方法的末尾加上‘return this‘這麼一條語句,不就實現級聯了~嘿嘿,下面是我做的一個小demo,相信大家看明白就會理解級聯了:

function $(e){  return new $.fn.init(e);}$.fn=$.prototype={    init:function(){      var elem=document.getElementById(arguments[0]);      this[0]=elem;    },    width:function(){      alert(this[0].style.width);      return this;    },    height:function(){      alert(this[0].style.height);      return this;    }  };$.fn.init.prototype=$.fn;$("dv").width().height();

 

 

 

 

《Javascript語言精粹》的學習(一).對象和函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.