2011-11-30 87 views
7

我發現在JavaScript中的特殊性(或者也許是我的瀏覽器的想法):爲什麼字符串變成`this`時會被破壞?

var s = "Hello, world"; 

function foo(arg) 
{ 
    console.log(arg); 
    console.log(this); 
} 

foo.call(s, s); 

運行與Firebug的控制檯上啓用,我得到:

Hello, world 
String { 0="H", 1="e", more...} 

爲什麼字符串自動獲得關在成爲this傳遞給foo之前變成奇怪的對象?

我把它稱爲一個奇怪的對象的原因是因爲jQuery對它扼殺。例如:

$.each(["one", "two", "three"], function(i, x) { 
    $('<p></p>').text(x) .appendTo('body'); // Works 
    $('<p></p>').text(this).appendTo('body'); // Doesn't work 
}); 
+0

好吧,'this'應該指'window',如果它不在一個函數。 – mc10

+0

有趣的行爲,假設涉及傳遞不正確數量的參數。如果可變數目的參數,我使用參數對象。 –

回答

4

this被強制到一個對象,即Object("test")內部調用。

(function() { 
    return this; 
}).call("test"); 

// returns same as `new String("test")` or `Object("test")` 

if the method is a function in non-strict mode ... primitive values will be boxed*.

注意,使用嚴格的模式的確不會返回原始值:

(function() { 
    "use strict"; 
    return this; 
}).call("test") === "test"; // true 

* Boxing a value of a value allocates an object instance and copies the value into the new object.

1

因爲this只是一個對象(我知道字符串是對象,但它們也字符串):

var s = "Hello, world"; 

function foo(arg) 
{ 
    console.log(typeof arg); // string 
    console.log(typeof this); // object 
} 

foo.call(s, s); 
1

使用foo.call(s1, s2),你調用函數foothis關鍵字設置爲s1。由於this必須是一個對象(所以不是原始值),它將轉換爲String對象。

一個字符串(通過s = "..."s = String("...")創建)的各個字符可以通過索引來訪問,因此

String { 0="H", 1="e", more...} 

function foo(arg) 
{ 
    console.log(arg); // passed as "Hello, world" 
    console.log(this); // passed as String("Hello, world") 
    console.log(this instanceof String); //True 
} 


代碼來演示的索引:

var i=0, s = "Hello, world"; 
for(; i<s.length; i++){ 
    console.log(i, s[i]); 
} 
/* Prints: 
    0 H 
    1 e 
    ... 
    */ 
*/ 
相關問題