2013-03-08 83 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