Effective JavaScript Item 37 認識this的隱式指向

來源:互聯網
上載者:User

標籤:return   tom   隱式   sep   str   全域對象   tracking   his   一個   

本系列作為Effective JavaScript的讀書筆記。

 

CSV資料通常都會被某種分隔字元進行分隔。所以在實現CSV Reader時,須要支援不同的分隔字元。那麼,非常自然的一種實現就是將分隔字元作為建構函式的參數。


function CSVReader(separators) {this.separators = separators || [","];this.regexp =new RegExp(this.separators.map(function(sep) {return "\\" + sep[0];}).join("|"));}

對於CSV Reader而言。它的工作原理是首先將讀入的字串依據分行符號切分成為一個個的行。然後對每行依據分隔字元進行切分成為一個個的單元。

所以,能夠使用map方法進行實現:


CSVReader.prototype.read = function(str) {var lines = str.trim().split(/\n/);return lines.map(function(line) {return line.split(this.regexp); // wrong this!});};var reader = new CSVReader();reader.read("a,b,c\nd,e,f\n"); // [["a,b,c"], ["d,e,f"]], wrong result

但是上述代碼中有一個錯誤:傳入到map函數中的回呼函數的this指向有問題。即當中的this.regexp並不能正確的引用到CSVReader執行個體的regexp屬性。因此,最後得到的結果也就是不對的了。

 

對於這個範例。在map的回呼函數中this指向的實際上是全域對象window。關於this在各種情境下的指向,在Item 18和Item 25中進行了介紹。

 

為了克服this的指向問題,map函數提供了第二個參數用來指定在其回呼函數中this的指向:


CSVReader.prototype.read = function(str) {var lines = str.trim().split(/\n/);return lines.map(function(line) {return line.split(this.regexp);}, this); // forward outer this-binding to callback};var reader = new CSVReader();reader.read("a,b,c\nd,e,f\n");// [["a","b","c"], ["d","e","f"]]

可是,並非全部的函數都如map考慮的這麼周全。假設map函數不能接受第二個參數作為this的指向。能夠使用以下的方法:


CSVReader.prototype.read = function(str) {var lines = str.trim().split(/\n/);var self = this; // save a reference to outer this-bindingreturn lines.map(function(line) {return line.split(self.regexp); // use outer this});};var reader = new CSVReader();reader.read("a,b,c\nd,e,f\n");// [["a","b","c"], ["d","e","f"]]

這樣的方法將this的引用儲存到了另外一個變數中,然後利用閉包的特性在map的回呼函數中對它進行訪問。一般會使用變數名self來儲存this的引用。當然使用諸如me。that也是可行的。

 

在ES5環境中。還能夠藉助於函數的bind方法來綁定this的指向(在Item 25中,對該方法進行了介紹):


CSVReader.prototype.read = function(str) {var lines = str.trim().split(/\n/);return lines.map(function(line) {return line.split(this.regexp);}.bind(this)); // bind to outer this-binding};var reader = new CSVReader();reader.read("a,b,c\nd,e,f\n");// [["a","b","c"], ["d","e","f"]]

總結

  1. 依據函數的調用方式的不同,this的指向也會不同。
  2. 使用self,me,that來儲存當前this的引用供其它函數使用。


Effective JavaScript Item 37 認識this的隱式指向

聯繫我們

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