2010-02-19 32 views
9

當使用原始類型(字符串,數字)作爲函數調用的this主題(作爲function.call()或函數apply())的第一個參數時,基本類型被提升爲其對象相當於(例如,一個字符串變成一個字符串)。爲什麼javascript在傳入function.apply()或function.call()時會改變原始類型?

舉例說明:

var f = function(x) { return [typeof(this), typeof(x)]; } 
var obj = '123' 
f.call(obj, obj) 
>>> ["object", "string"] 

也就是說,「本」成爲一個對象(這是,我已經檢查一個String對象),而第二個參數來調用成爲第一個參數函數「f」 ,並保持原始字符串。

對象都是均爲「123」,但微妙的東西不起作用(例如,它們在「==」方面是相等的,而不是在「===」方面)。

我注意到在Chrome和Firefox中都有這種行爲,所以我假設它有一個特定的原因。我搜索了,但沒有找到任何解釋。我會很感激任何解釋,希望通過某種鏈接來解釋圍繞它的規則以及它爲什麼會發生。

回答

10

這似乎是正確的行爲。

http://bclary.com/2004/11/07/#a-15.3.4.4

Function.prototype.call - 被調用函數傳遞ToObject(thisArg)作爲該值。

ToObject「根據下面的其參數轉換爲Object類型的值」:

字符串 - 創建其[[值]]屬性被設置爲的值的新String對象串。

+0

真的很好找到J-P。非常有趣的問題(和答案)。少一個JavaScript WTF對我來說至少=) – anddoutoi 2010-02-19 08:59:38

+0

它不僅看起來是正確的,而且完全正確。優秀的來源。 – 2010-02-19 09:11:32

+0

啊,非常感謝! 我很想知道爲什麼toObject()被調用,但我不認爲這種推理是在規範的任何地方。 我記得在某處讀取原始字符串上的方法是通過將它們轉換爲一個String對象並返回來解決的,所以這可能是一個類似的情況...... – gfxmonk 2010-02-19 10:52:48

2

Javascript函數調用中的第一個參數&應用方法確定在哪個上下文中運行所請求的函數。 因此,這將始終是一個對象

爲了說明這一點,檢出以下示例

function totest() 
{ 
    this.ff = function(x) { 
     this.test(x); 
    }; 

    this.test = function(x) { 
     alert(x); 
    } 

} 

function totest1() 
{ 
this.test = function(x) { 
    alert(x); 
} 

} 

function fun() 
{ 
    var obj = new totest(); 
    var obj1 = new totest1(); 
    obj.ff('hi'); //Runs fine without any problem 
    obj.ff.call(obj, 'sam') ; //Runs fine without any problem 
    obj.ff.call(this, 'sam'); //throws an error 
    obj.ff.call(obj1, 'sam'); //will be executed in the context of totest1 

} 

obj.ff.call(此, 'SAM')引發錯誤。 爲什麼

因爲我們指定obj.ff方法在樂趣(或窗口)的上下文中執行而不是在totest的上下文中執行。 obj.ff.call(obj1,'sam')告訴調用在totest1()的上下文中執行ff,並且它可以工作,因爲它已經進行了方法測試。

所以這必須是對象。

而調用方法中的剩餘參數是要執行的方法的實際參數。所以他們會根據給定的值推斷出類型。

希望您能理解現在

+0

在這種情況下類型錯誤的原因是因爲'ff'函數調用'this.test'。 在'fun'內,'this'的值實際上被設置爲全局'window'對象(這是普通函數中'this'的默認值)。因此''ff'被調用,'this'等於'window',窗口對象根本沒有叫'test'的方法。 – gfxmonk 2010-02-19 10:55:51

+0

@ gfxmonk,的確如此..它意味着param1在調用方法中必須是一個對象,所以它可以在param1對象的上下文中調用ff方法。 這就是分配給param1的任何類型值(不管是否是原始類型)的原因都將被轉換爲對象。我已經用一個更多的功能更新了答案。請退房 – RameshVel 2010-02-19 11:16:19

0

短期和簡單的:第一個參數變成一個對象的情況下,這是一個基本類型的,因爲正如你指出的那樣,它可能被this在所謂的簡稱功能。由於this必須引用一個對象,因此運行時環境確保實際上有要引用的對象。想想你將如何實施它,你可能會得出同樣的結論。好問題。

P.S .:我很欣賞Ramesh的回答,這在技術上是說明性的,但是想爲不耐煩的讀者添加一個答案。

相關問題