我知道可以添加到
这样的函数的原型中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 :(得分: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
创建对象?
更新:以下是实现所需内容的众多可行方法之一:
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中构造对象。这一切都取决于情况和你的个人编码风格。
答案 1 :(得分:0)
我确实让它与
一起使用main.prototype.get.prototype.registration();
但请记住,正如@the_system所提到的那样,你不能直接使用main.get
;你必须通过原型来找到get
函数(和registration
函数的相似性)。
答案 2 :(得分:0)
这只是我个人的观点,但我总是发现JavaScript中的原型继承模型难以理解。在编写代码时很难理解,并且在6个月后维护代码时更难以推理。
但是,我认为你问的是这样的:“我可以编写一个从匿名类继承其成员方法的类吗?”当你用这种方式改写它时,我认为很明显这种方法存在不确定的价值。编写类的整个目的是支持简单的抽象和封装,同时保持组合紧密。
使用传统的对象,ala:
会更直接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];
};
从这里开始,菊花链继承的类变得微不足道。我只是将其从我的一个项目中拉出来,所以并非所有这些语义都适用于你 - 这只是为了说明一种以更容易推理的方式对行为进行功能化的方法。
答案 3 :(得分: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();