2011-11-30 89 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 
    ... 
    */ 
*/ 
相关问题