2012-08-05 39 views
3

我正在閱讀Crockford的'JS:The Good Parts'。他有兩個使用這個例子,我不明白爲什麼有一次他使用this和另一個他使用that在這些例子中調用'this'有什麼區別?

第一個例子:

String.method('deentify', function() { 
    var entity = { 
     quot: '"', 
     lt:  '<', 
     gt:  '<' 
    }; 

    return function() { 
     return this.replace(/&([^&;]+);/g, 
      function (a, b) { 
       var r = entity[b]; 
       return typeof r === 'string' ? r : a; 
      } 
     ); 
    }; 
}()); 
document.writeln('&lt;&quot;&gt;'.deentify()); 

第二個例子:

Function.method('curry', function() { 
    var args = arguments, that = this; 
    return function() { 
     return that.apply(null, args.concat(arguments)); 
    }; 
}); 
var add1 = add.curry(1); 
document.writeln(add1(6)); 

爲什麼能夠在第一示例性接入this直接?這個例子和後面的例子有什麼區別?

+1

什麼是'String.method'或'Function.method' ?! – Mohsen 2012-08-05 08:27:38

+0

而且在你的第一個範例中,立即執行的函數是全局的。嘗試'console.log(function(){console.log(this)}())'。當你不通過範圍時,它將是全球性的。(瀏覽器中的'Window') – Mohsen 2012-08-05 09:11:33

+0

它們是自定義添加的輔助函數,用於將方法添加到指定的原型;即Function.method爲函數原型添加了一個方法,等等。 – Avery 2012-08-07 04:42:54

回答

3

當你做obj.f(),this裏面的功能f將參考obj

在第一個示例中,在字符串上調用deentify()。在那個函數中,他只需要函數被調用的對象,即字符串,這是deentify()函數中要引用的內容。

我們爲什麼需要that

add1功能需要存儲到原來的add函數的引用莫名其妙。 add1不能使用this,因爲它是而不是稱爲add.add1。這通過在that上創建閉包來克服,其中他保存了對執行curry()的函數的引用(示例中的add())。

當您撥打add.curry()時,this將參考add函數。 (因爲你在add上叫curry())。由於咖喱功能內部的關閉,that將保持其值,並且當調用add1()時仍將參考add功能。

如果在curry()返回的函數內部使用了this,它將引用window對象。

Function.method('curry', function() { 
    var args = arguments, 
     that = this; //reference to add 
    return function() { 
     //`apply` calls add 
     return that.apply(null, args.concat(arguments)); 
    }; 
}); 
var add1 = add.curry(1); 
document.writeln(add1(6)); 

注意:看到這一點很重要,即在第一個片段的第一return表示deentify()功能,而在第二個片段的第一return表示返回值的的curry()功能

如果您想了解使咖喱也可以使用的魔術,請在評論中提問,我會很樂意詳細說明。

+0

很好的解釋。完全合理。我應該更加關注調用上下文。我瞭解申請是如何運作的,但謝謝你的提議,解釋也一樣! – Avery 2012-08-07 04:47:49

+0

@Avery我很高興你喜歡它。感謝您的反饋。 – phant0m 2012-08-07 05:56:06