2013-10-03 53 views
0

我不完全知道如何問這個問題,所以我會用例子做。說我有這樣的設置:功能與對象的構造

var x = function() { 
    console.log('YAY!'); 
}; 
x.test0 = 0; 
x.test1 = 1; 
x.test2 = "hello world"; 

如預期那樣工作:

x(); // YAY! 
x.test0 // 0 
x.test2 // "hello world" 

現在,我想知道如何設置了先用一個對象開始。我嘗試使用構造函數添加函數,但這不起作用。

var x = { 
    test0 : 0, 
    test1 : 1, 
    test2 : 'hello world', 
    constructor: function() { 
    console.log('YAY!'); 
    } 
} 

x(); // object is not a function 
x.test0 // 0 
x.test2 // "hello world"; 

我試過其他瘋狂的東西,但似乎沒有任何工作。

任何想法?或者我堅持這樣做的第一種方式?

+0

你試圖解決什麼問題? – Pointy

+0

我只想知道如何從一個對象開始,並附加一個函數,所以'x()'運行該函數。 – Mottie

+2

函數是唯一可調用的本機EMCAScript類型。你不能進行非函數調用,因爲ECMAScript沒有公開任何方式來操作對象的[[Call]]內部屬性。如果你想把一個對象變成一個函數,爲什麼不把它作爲一個函數呢? – apsillers

回答

3

正如您的第一個示例所示,JavaScript中的函數是對象並且可以具有屬性。

ECMAScript中定義的 「internal properties」(和內部方法)對象。這些內部屬性有助於定義對象的狀態,但並不是所有對象的內部屬性都可以直接從代碼中設置。我們使用雙方括號表示內部屬性名稱,如[[Foo]]

當你調用像foo()功能,運行對象的[[Call]]內部方法。但是,只有函數對象具有[[Call]]內部方法。無法設置或更改非主機對象的[[Call]]方法;它是在定義對象時設置的,並且沒有ECMAScript定義的機制來更改它。 (通過瀏覽器或其他執行環境提供,可以通過不同的規則行事「主機」對象的對象。除非你正在編寫一個瀏覽器,你可能不需要考慮這個例外。)

因此,如果您定義一個函數

foo = function() { doStuff(); return 5; }; 

該功能(其被分配給變量foo)具有永久[[Call]]方法(每個功能創建規則中section 13.2),它運行doStuff並返回5

如果你有一個非函數對象

foo = { }; 

該對象缺乏[[Call]]屬性。有沒有辦法給它一個[[Call]]屬性,因爲非主機的對象可以在定義時只設置[[Call]]。邏輯內部屬性[[Call]]不對應於實際代碼中可訪問的任何對象屬性。

總而言之,無法調用非函數對象。如果你想要一個對象被調用,那麼首先將它定義爲一個函數,就像你在第一個例子中做的那樣。

+0

謝謝,那完全回答了我的問題:) – Mottie

0

你不能只創建一個對象,並在以後執行它,彷彿它是一個函數。

你可以圍繞做的其他方式,如在JavaScript函數是一個對象:

x.prop=1; 
console.log(x.prop); 

function x() { 
    return true; 
} 
0

沒有得到你想要什麼,你要什麼樣的面向對象的?這可能有幫助

function x(){ 
    this.test0 = 0; 
    this.test1 = 1; 
    this.test2 = 'hello word'; 
    console.log('Wow!'); 
} 

var y = new x(); // new object of x PRINTS WOW and set's default values 
console.log(y.test0) // 0 
console.log(y.test2) // "hello world"; 
1

簡而言之,你不能。爲什麼?因爲兩個對象的類型都是不同的,所以首先一個Function Object,然後返回一個標準對象。所以都從不同的祖先繼承。這裏唯一的可能性是,如果你可以將對象轉換爲函數,並且原生沒有可用的JavaScript。但是,您可以使用自己的投射方法。

function toFunction (obj, fnProp) { 
    var fn = function() {}; 
    if (typeof obj[fnProp] !== 'function') return fn; 
    else { 
     fn = obj[fnProp]; 
     for (prop in obj) { 
      fn[prop] = obj[prop]; 
     } 
    } 
    return fn; 
} 


var z = toFunction(y, 'prototype'); // with your example