2013-03-08 51 views
1

函數原型的,我知道,它可能添加到一個函數,使得原型在Javascript

function main(){} 
main.prototype.load = function() 
{ 

} 
... 

的原型和運行名爲main.load功能。

是否可以在原型中創建函數的原型?換句話說,我可以做這樣的事情:

main.prototype.get = function(){} 
main.prototype.get.prototype.registration = function() 
{ 
    // load registration info 
} 

,並呼籲使用main.get.registration();功能?

當我嘗試這樣做,我給在控制檯此錯誤消息:

Uncaught TypeError: Object function(){} has no method 'registration'

編輯:我打電話new main();後這樣做。所以我會做這樣的事情

var thisMain = new main(); 
thisMain.get.registration(); 
+0

如果你嘗試什麼? – zerkms 2013-03-08 03:14:10

+1

它應該是可能的,但它似乎不是一個好主意。如果'this'已經讓JS和一個原型混淆了,那麼想象兩個... – elclanrs 2013-03-08 03:14:27

+1

首先,您無法直接從'main'訪問'load'或'get'。您可以從其'.prototype'或通過'new'調用'new'創建的實例進行訪問。其次,您可以在'main.prototype'上放置'.get',但'get'中的實例和'main'中的實例之間沒有特別的關係。 – 2013-03-08 03:19:19

回答

2

我覺得你誤解了一下原型。

給定函數Foo,Foo.prototype不是Foo對象的原型。這是將分配給使用new Foo()創建的對象的原型。例如:

// This is a constructor that creates objects whose prototype is Person.prototype 
var Person = function(name) { 
    this.name = name; 
} 
Person.prototype.sayHello = function() { 
    console.log("Hello, my name is " + this.name); 
} 
var drew = new Person('Drew'); 
drew.sayHello(); // <-- Logs a message 
drew.__proto__; // <-- Not part of the Javascript spec, but it some browsers this is a reference to Person.prototype 

你main.get.registration可以在沒有原型實現:

main = function() {/* do stuff*/} 
main.get = function() {/* this is a getter function? */} 
main.get.registration = function() {/* I don't know what this does */} 

你是希望什麼樣的接口或API來創建?它是否涉及使用new創建對象?

UPDATE:這裏是實現你想要的多種可能方式之一:

main = function() { 
    // store a reference to this instance. 
    var self = this; 
    // Construct the get object. It doesn't need to be a function because it's never invoked 
    this.get = {}; 
    this.get.registration = function() { 
     // Use self to refer to the specific instance of main you're interacting with. 
     retrieveRegistrationFor(self); // <-- pseudo-code 
    } 
} 

更新2:下面介紹如何使用構造構造get對象,讓您使用原型的一切。我已經大寫了你的構造函數的名字,這是一個有助於區分正常函數/方法和構造函數的最佳實踐。

// Constructor for the get object. This is only ever invoked in Main's constructor. 
Getter = function(mainInstance) { 
    this.self = mainInstance; 
} 
Getter.prototype.registration = function() { 
    retrieveRegistrationFor(this.self); // <-- pseudo-code 
} 

Main = function() { 
    // Construct the get object and attach it to this object. 
    this.get = new Getter(this); 
} 

正如其他答案指出的,有很多方法來構建Javascript中的對象。這一切都取決於情況和你的個人編碼風格。

+0

我想我需要在我的回答中解釋得更好一點,但是是的,它涉及到使用'new'。我會做'var thisMain = new main(); thisMain.get.registration();'這是我現在做的,但是當我嘗試這樣做時,它會吐出問題中提到的錯誤。 – josh 2013-03-08 03:27:46

+0

你是不是故意說'var thisMain = new main(); thisMain.get.registration()'?另外,你什麼時候調用'get'函數?如果你永遠不會這樣做,那麼'get'可以是一個普通的對象而不是一個函數。 – cspotcode 2013-03-08 03:29:36

+0

我的意思是'thisMain.get.registration()',但是我在事後才發現它。我從不直接調用'get'函數,只是'main',這可能是我的問題。 – josh 2013-03-08 03:30:51

0

我沒有得到它與

main.prototype.get.prototype.registration(); 

的工作,但要記住,作爲@the_system提到的,你不能直接使用main.get;您必須通過原型才能找到get函數(以及與registration函數的相似性)。

0

這只是我個人的看法,但我總是發現JavaScript中的典型繼承模型很難找到。在編寫代碼時很難推理,並且在6個月後維護代碼更加困難。

但是,我想你問的只是這個:「我可以寫一個類,它從匿名類繼承其成員的方法嗎?」當你用這種方式重新翻譯它時,我認爲很明顯,這種方法存在不確定的價值。編寫類的全部目的是支持簡單的抽象和封裝,同時保持構圖嚴密。

這將是更容易使用的傳統對象,鼻翼:

var main = { 
    get: { 
     registration: function() { 
      //TODO 
     } 
    } 
} 

main.get.registration()是簡單得很。如果你可以利用Object.create()和Object.defineProperties()來做到這一點,那就更好了。

如果你絕對必須使用原型繼承,我喜歡simple Function.prototype extension that Mr. Kistner proposes

Function.prototype.inheritsFrom = function(parentClassOrObject) { 
    if (parentClassOrObject.constructor === Function) { 
     //Normal Inheritance 
     this.prototype = new parentClassOrObject; 
     this.prototype.constructor = this; 
     this.prototype.parent = parentClassOrObject.prototype; 
    } else { 
     //Pure Virtual Inheritance 
     this.prototype = parentClassOrObject; 
     this.prototype.constructor = this; 
     this.prototype.parent = parentClassOrObject; 
    } 
    return this; 
}; 

這可以讓你再創作類和繼承,像這樣:

/*** 
* Method to create a Class with optional inheritance. 
* Generally, I oppose this semantic in JS: 
* partly because of the ineffability of the 'this' operator, 
* and partly because of the difficulty in grokking this. 
* What we're really saying here (through the wonders of functional programming) is this: 
* 
*  var MyClass1 = function(param1) { 
*   var ret = this; 
*   ret.id = param1; 
*   return ret; 
*  }; 
* 
*  var MyClass2 = function(param1, param2) { 
*   var ret = this; 
*   MyClass1.apply(this, Array.prototype.slice.call(arguments, 0)); 
*   ret.name = param2; 
*   return ret; 
*  }; 
* 
*  MyClass2.prototype = new MyClass1; 
*  MyClass2.prototype.constructor = MyClass1; 
*  MyClass2.prototype.parent = MyClass1.prototype; 
* 
* I find this whole mode of operation as dull as it is stupid. 
* Nonetheless, there are occasions when the convention is suitable for type/instance checking 
* 
* Obviously, this method has very little utility if you are not using prototypal inheritance 
*/ 
var MyClassCreatorMethod = function(name, inheritsFrom, callBack) { 
    var obj = Object.create(null); 
    obj[name] = function() { 
     try { 
      if(inheritsFrom) { 
       inheritsFrom.apply(this, Array.prototype.slice.call(arguments, 0)); 
      } 
      callBack.apply(this, Array.prototype.slice.call(arguments, 0)); 
     } catch(e) { 
      //do something 
     } 
    }; 
    if(inheritsFrom) { 
     obj[name].inheritsFrom(inheritsFrom); 
    } 
    return obj[name]; 
}; 

從這裏,它變得微不足道菊花鏈繼承類。我只是把它從我的一個項目中拉出來,所以並不是所有的這些語義都適用於你 - 這只是爲了說明一種以更容易推理的方式對行爲進行功能化的方法。

0

也許你想做的事是這樣的:

function main(){} 
main.prototype.load = function() 
{ 

}; 

main.prototype.get = function(){}; 
main.prototype.get.prototype.registration = function() 
{ 
    // load registration info 
    alert('hi, I\'m working'); 
}; 

var thisMain = new main(); 
var other = new thisMain.get(); 
other.registration(); 
+0

在這裏嘗試http://jsfiddle.net/8He4E/ – eburgos 2013-03-08 03:41:55