【发布时间】:2017-01-10 11:54:59
【问题描述】:
我正在构建一个 JavaScript 应用程序,其中我有一个主要的 JS 对象,我将为这篇文章调用 App。
App 对象有一个 modules 属性,该属性包含一组 Module 对象,其中模块名称作为 App.modules 上的对象属性名称。
module 是用户为我的应用贡献的附加组件,它将使用 Prototypes 扩展 CoreModule 对象。
App.modules 对象会像这样向对象添加新模块...
App.modules[moduleName] = module-object-instance;
所以如果注册了 1 个模块,我所描述的总共有 3 个对象....
- 应用
- 核心模块
- userBuiltMOdule
在我的 App 代码中,我希望有一个 registerModule() 函数来执行此操作...
// this will create a new instance of "moduleName" and add it to this.modules[moduleName] object
// for example I am hardcoding the module name as theres 1 module now
registerModule: function(moduleName, moduleClass) {
// create new instance of module
this.modules[moduleName] = new bookmarksModule();
// run moduleName.init() function from the main App
this.modules[moduleName].init();
console.log('App.registerModulemoduleName) function ran and created new instance of '+moduleName+'object');
},
现在要从我的CoreModule 扩展一个用户模块用户模块的...
createModule: function(moduleObject){
var moduleCoreInstance = Object.create(this);
// add sub-modules properties and functions to CoreModule
Object.keys(moduleObject).forEach(function(key){
moduleCoreInstance[key] = moduleObject[key];
});
return moduleCoreInstance;
},
现在我要创建一个用户模块...
var bookmarksModule = ModuleCore.createModule({
name: 'bookmarks',
init: function(){
console.log('bookmarksModule init() function ran from App object '+this.name+')');
}
});
bookmarksModule 现在有name、init()、registerSidebar() from the CoreModule
现在是我这个系统的问题...
在我的 App.registerMOdule()` 函数中我无法使用:
// create new instance of module
this.modules[moduleName] = new bookmarksModule();
这将给出如下错误:
Uncaught TypeError: bookmarksModule is not a constructor
at App.registerModule (yuzulat.js:51)
at App.init (yuzulat.js:43)
如果我用它来切换代码,它会起作用:
this.modules[moduleName] = bookmarksModule;
其中bookmarksModule 是调用var bookmarksModule = ModuleCore.createModule() 的用户模块
所以我的问题是,有没有办法像我现在一样从CoreModule 扩展,但允许我的App.registerModule() 创建用户模块的新实例?
下面是我的完整示例代码...
JSBin 演示 - http://jsbin.com/yuzulat/1/edit?js,console,output
var ModuleCore = {
// add ModuleCore prototype functions to the new sub module as well as pass in the sub-modules properties and functions and return to
// the sub-module so the sub-modules prototype will have CoreModules properties and function and its own properties and function merged
// into its prototype
createModule: function(moduleObject){
var moduleCoreInstance = Object.create(this);
// add sub-modules properties and functions to CoreModule
Object.keys(moduleObject).forEach(function(key){
moduleCoreInstance[key] = moduleObject[key];
});
return moduleCoreInstance;
},
registerSidebar: function(){
console.log('registerSidebar(sidebar options for module '+this.name+')');
}
};
var bookmarksModule = ModuleCore.createModule({
name: 'bookmarks',
init: function(){
console.log('bookmarksModule init() function ran from App object '+this.name+')');
}
});
(function() {
function App() {
this.settings = {};
this.modules = {};
};
App.prototype = {
// run registerModules
init: function(bookmarksModule) {
console.log('App.init() function ran');
// call App.registerModule() and pass in bookmarksModule module name
this.registerModule('bookmarksModule', bookmarksModule);
},
// this will create a new instance of "moduleName" and add it to this.modules[moduleName] object
// for example I am hardcoding the module name as theres 1 module now
registerModule: function(moduleName, moduleClass) {
// create new instance of module
this.modules[moduleName] = new bookmarksModule();
//this.modules[moduleName] = moduleClass;
// run moduleName.init() function from the main App
this.modules[moduleName].init();
console.log('App.registerModulemoduleName) function ran and created new instance of moduleName object');
},
// itterate this.modules object and call this.initModules() function on each module object
registerModules: function() {
console.log('App.registerModules() function ran');
}
};
window.App = App;
})();
// create new instance of App
var App = new App();
App.init(bookmarksModule);
// call App.registerModule() and pass in bookmarksModule module name
App.registerModule('bookmarksModule', bookmarksModule);
【问题讨论】:
-
this.modules[moduleName] = new bookmarksModule();?moduleClass参数呢? -
@Poster
createModule给出一个普通对象,new与函数一起使用。 -
@procrastinator
moduleClass你是在问它在哪里还是说它创建了一个对象的实例?如果第一个moduleClass与上面示例用户创建的模块中的var bookmarksModule = ModuleCore.createModule()相同 -
@JasonDavis 我的意思是你有一个名为
moduleClass的参数并且你从不使用它。看起来很奇怪。 -
@procrastinator 在您发布此内容时更新了评论。只是从我正在试验的 2 个不同的演示中创建这篇文章
标签: javascript inheritance prototype