2

我知道可以添加到函数的原型中,这样

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();
4

4 回答 4

4

我认为您对原型有点误解。

给定一个函数FooFoo.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 中构造对象。这完全取决于情况和您的个人编码风格。

于 2013-03-08T03:21:40.360 回答
0

我确实让它与它一起工作

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

但是请记住,正如@the_system 提到的,您不能main.get直接使用;您必须通过原型才能找到get功能(以及与功能的相似性registration)。

于 2013-03-08T03:21:16.780 回答
0

这只是我个人的看法,但我一直觉得 JavaScript 中的原型继承模型很难理解。编写代码时很难推理,6个月后维护代码更难推理。

但是,我认为您要问的实际上只是这样:“我可以编写一个从匿名类继承其成员方法的类吗?” 当你这样改写它时,我认为很明显这种方法存在不确定的价值。编写类的全部目的是支持简单的抽象和封装,同时保持组合紧密。

使用传统对象会更直接,ala:

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

而且main.get.registration()很简单。如果您可以利用 Object.create() 和 Object.defineProperties() 来做到这一点,那就更好了。

如果您绝对必须使用原型继承,我喜欢Kistner 先生提出的简单 Function.prototype 扩展

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];
};

从这里开始,菊花链继承类变得微不足道。我刚刚从我的一个项目中提取了这个,所以并不是所有的语义都适用于你——它只是为了说明一种以更容易理解的方式对行为进行功能化的方法。

于 2013-03-08T03:37:15.440 回答
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();
于 2013-03-08T03:41:18.260 回答