2012-12-06 53 views
1
var foo = function(){alert('foo')} 
function bar(){alert('bar')} 

爲什麼foo.prototype指向對象,但在命名的功能bar.prototype點本身之間的原型區別?函數的聲明和表達

我應該補充說,這種行爲是從瀏覽器控制檯觀察到的。

+0

對不起。你想說什麼? 'foo.prototype'和'bar.prototype'都應該分別指向'foo'和'bar'的'prototype'對象。 –

+0

你的問題沒有任何意義 - 'foo.prototype'不指向'Object','bar.prototype'不指向'bar':http://jsfiddle.net/2xkpC/ –

+0

@AaditMShah你是對的,但是Chrome控制檯在請求函數原型時會記錄函數名稱。我會一直刪除我的答案,直到我弄清楚爲止。 – bfavaretto

回答

5

如果您使用Chrome等控制檯記錄對象的價值,那麼我建議您不要這樣做。與其他瀏覽器控制檯一樣,Chrome控制檯也會格式化原型對象的輸出。

因此,對於一個命名的函數,它會記錄該函數的name,但對於一個未命名的函數,它將簡單地記錄Object。這並不意味着函數的prototype指向Object或函數本身。這就是控制檯向你展示的內容(有人應該爲此提出起訴)。請親自看看:http://jsfiddle.net/2xkpC/

它是如何從它的prototype中知道函數的名稱?那麼,函數的原型有一個名爲constructor的屬性,該屬性指向函數本身,並且函數的名稱作爲字符串存儲在函數的名爲name的屬性中。所以,如果你登錄一個prototype對象,然後它會顯示prototype.constructor.name || "Object"

var foo = function(){alert('foo')} 
console.log(foo.prototype); // logs "Object" 

function bar(){alert('bar')} 
console.log(bar.prototype); // logs bar.prototype.constructor.name 

在這裏看到演示:http://jsfiddle.net/4bWfn/

如果你打開控制檯,並單擊記錄的輸出接近該三角形中,那麼你會看到constructor和原型對象的__proto__屬性。在constructor下,您還會看到name屬性。

想了解更多關於在JavaScript中繼承和prototype對象讀取這樣的回答:https://stackoverflow.com/a/8096017/783743

+0

同意,控制檯的行爲非常具有誤導性。這種行爲的可能原因是爲新實例記錄構造函數的名字,即'var b = new bar();的console.log(b)中; // bar'。 – bfavaretto

+0

美麗的答案,謝謝。 – mystrdat

-1

因爲在你的例子中var foo它是指向匿名函數的指針。

比較

var foo = function me(){alert('foo');} 
test=foo; 
console.log(test.prototype); 

這裏var foo是指針命名函數。

+0

'function(){// do something}'本身匿名函數沒有上下文,沒有理由把它分成兩種不同的類型 –

+0

是的,我的例子是和OP例子比較,我的示例顯示了命名函數,它幾乎等於@ bfavaretto的答案 –