簡體   English   中英

函數與對象構造函數

[英]Function versus Object constructor

我不確定如何問這個問題,因此我將通過示例進行說明。 說我有這個設置:

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";

我嘗試了其他瘋狂的方法,但似乎無濟於事。

有任何想法嗎? 還是我堅持做第一件事?

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

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

當您調用foo()類的函數時,您將運行對象的[[Call]]內部方法。 但是,僅功能對象具有[[Call]]內部方法。 不能設置或更改非宿主對象的[[Call]]方法。 它是在定義對象時設置的,並且ECMAScript沒有定義更改它的機制。 (“主機”對象是瀏覽器或其他執行環境提供的對象,可以按照不同的規則進行播放。除非編寫瀏覽器,否則可能不需要考慮此異常。)

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

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

該函數(已分配給變量foo )具有一個永久的[[Call]]方法(根據13.2節中的函數創建規則),該方法運行doStuff並返回5

如果您有非功能性物件

foo = { };

該對象缺少[[Call]]屬性。 無法給它提供[[Call]]屬性,因為非宿主對象只能在定義時設置[[Call]] 邏輯內部屬性[[Call]]與實際代碼中可訪問的任何對象屬性都不對應。

總而言之,使非功能對象可調用是不可能的。 如果希望對象是可調用的,則像在第一個示例中一樣,首先將其定義為函數。

簡單地說,你做不到。 為什么? 因為兩個對象的類型不同,所以第一個對象是Function Object ,第二個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

您不能只是創建一個對象,然后再將其當作函數來運行。

您可以用另一種方法來實現,因為在JavaScript中,函數是對象:

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

function x() {
    return true;
}

沒有得到您想要的東西,您是否想要面向對象的東西? 這可能會有所幫助

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";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM