2011-08-26 16 views
1

我典型的例子就是下面的僞代碼:有沒有在JavaScript中實例化一個不一定是函數的對象的方法?

var kind = ...; 
... 
var type = new kind(); 
... 
var person = new type(); 
... 
var john = new person(); 

但這裏的問題是,type不是一個功能,使new type()將無法​​正常工作。 是否有一個特定的屬性,您可以添加到對象以使其可以被new接受?

最重要的是原型鏈,這對我來說很重要,那就是person.[[Prototype]]應該是type等,以防new不可能的情況。

創建子類型鏈不是一個選項。這裏typeperson的元類型,而不是它的超類型。同樣kind是一個元元類型。下面的測試可以明確的要求: 當全部完成,我希望這些積極的測試:

console.log(john instanceof person); // should be true 
console.log(person instanceof type); // should be true 
console.log(type instanceof kind);  // should be true 

這些負面測試:

console.log(john instanceof type);  // should be false 
console.log(john instanceof kind);  // should be false 
console.log(person instanceof kind); // should be false 

我聽說,通過分配到__proto__屬性的一個可以做這種魔術,但不知道如何。顯然,一個便攜式解決方案(例如使用Object.create)是非常受歡迎的,如果有的話。

+0

那麼,你只是試圖創建一個「人」,這是一個「類型」,這是一種「親切」?所以每當你創造一個新的「人」時,你就隱含地創造出一種新的「種類」,並自動獲得該類型的所有功能? –

+0

不,我不想要一個子類型鏈,我想'person'是'type'的實例,就像'john'是'person'的實例一樣。 – Saintali

+0

這很混亂,特別是你對FunkyFresh的回答發表評論。 1)你想要一個is-a類型的關係嗎? 2)你不想從基類繼承任何結構或功能? –

回答

2

有沒有可以添加到一個對象,使其接受new一個特定的屬性?

號,根據ECMAScript的第11.2.2控制這種能力的屬性被稱爲[[Construct]],並且你可以在方括號告訴,這是一個內部屬性。它不受ECMAScript代碼的影響。根據第13.2節,創建函數對象時,唯一時間[[Construct]]被分配。

您必須在ECMAScript第三版中進行原型繼承的唯一途徑是通過使用prototype屬性創建構造函數。即使你不打算對它做任何事情,你也必須創建該功能。 This question涵蓋了類/實例系統的常見模式。

在ECMA 5中,您確實獲得了Object.create()。對於不支持它目前還沒有瀏覽器的兼容性,可以使用臨時構造函數,什麼也不做,如實施Object.create()一部分自己:

if (!('create' in Object)) { 
    Object.create= function(proto, props /* optional */) { 
     var obj; 
     if (proto===null) { 
      obj= {}; 
     } else { 
      Object.create._construct.prototype= proto; 
      obj= new Object.create._construct(); 
      Object.create._construct.prototype= null; 
     } 
     if (props!==undefined) 
      Object.defineProperties(obj, props); 
     return obj; 
    }; 
    Object.create._construct= function() {}; 
} 

(當然Object.defineProperties是另一種方法ES5你」 d具有勻場中,如果你想爲支持,這是不可能的純ES3實現,只能用其他瀏覽器擴展。)

我聽說,通過分配到__proto__財產可以做一些神奇的這種,但不知道如何。

這總是非標準的,甚至在Firefox中也會消失。不要打擾它。

+0

我希望像'Function.create(proto,f)'這樣的東西存在,並返回一個等於'f'的函數,但是與給定的原型一樣。然後我可以說'type = Function.create(kind,function(){})' – Saintali

+0

@saintali:不是原生的。不過,你可以在很少的代碼中自己實現一個,例如,鏈接問題中的'var type = kind.makeSubclass()'。 – bobince

+0

'__proto__'無處不在,不僅僅在Firefox中。儘管如此,直到所有使用案例都可以與其他材料一起使用。 (其目的是在對象創建時對象的[[Prototype]]變爲不可變的。) – gsnedders

0

嘗試new type.constructor(),它將創建一個與type相同類型的新對象,這可能是您想要的。

+0

'type.constructor'是'kind',所以這會創建一個新的'kind',而不是一個新的'type' – Saintali

0

據我所知,您想type繼承kind?是?

如果是這樣......

function kind() {}; 
kind.prototype.name = "fred"; 
function type() {}; 
type.prototype = new kind(); 

var person = new type(); 
colsole.log(person.name); //fred 

console.log(person instanceof type); // true 
console.log(person instanceof kind); // true 

console.log(type.prototype instanceof kind); //true 
+0

我想這個'instanceof'鏈是真的:'john instanceof person &&人類實例類型&&類型類的實例' – Saintali

+0

查看更新。正如你所看到的,person是它繼承的所有類型的一個實例。 –

+0

謝謝,但'person instanceof kind'有問題,請參閱最新的問題。 – Saintali

相關問題