javascript object literal pattern with multiple instances
I have developed a little javscript widget to turn some nested <ul>
blocks into a windows explorer style browser. I have recently learnt about the object literal pattern and decided to give it a go, so the organisation of my code is something like this:
var myExplorer = {
init : function(settings) {
myExplorer.config = {
$wrapper : $('#explorerCategories'),
$contentHolder : $j('#categoryContent'),
loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />'
}
// provide for custom configuration via init()
if (settings && typeof(settings) == 'object') {
$.extend(myExplorer.config, settings);
}
// some more code...
},
createExpanderLink : function() {
// mo开发者_StackOverflow社区re code
},
anotherMethod : function() {
// etc
}
}
Then in my page I set up my explorer with:
$j(function () {
myExplorer.init();
}
This all works fine by the way. The problem is when I want to have more then one of these explorer style widgets on the same page. I tried passing in the different settings:
$j(function () {
// first instance
myExplorer.init();
//second instance
var settings = {
$wrapper : $('#explorerCategories2'),
$contentHolder : $j('#categoryContent2')
}
myExplorer.init(settings);
}
But this simply overwrites the config vales for the first instance which effectively breaks it. I'm beginning to realise that the object literal pattern isn't the way to go here but I'm not sure what is. Can anyone offer any pointers?
Use a function instead on an object literal, so you can instantiate multiple objects of the widget using the new
keyword.
function myExplorer(settings) {
// init code here, this refers to the current object
// we're not using a global object like myWindow anymore
this.config = {
$wrapper : $('#explorerCategories'),
$contentHolder : $j('#categoryContent'),
..
};
// provide for custom configuration
if (settings && typeof(settings) == 'object') {
$.extend(this.config, settings);
}
this.someFunction = function() {
..
};
this.otherFunction = function() {
};
}
Instantate as many objects of this widget as needed using,
var foo = new myExplorer({ .. });
var bar = new myExplorer({ .. });
...
What about this?
var myExplorer = function(settings) { var o = { init: function() { this.somevalue = settings; }, whatever: function() { } }; o.init(); return o; }; var exp1 = myExplorer('something'); var exp2 = myExplorer('anything'); console.log(exp1.somevalue); //something console.log(exp2.somevalue); //anything
Use the following code to achieve this, remember about the 'public API' (so that the 'internal' function will be visible 'outside'):
var myExplorer = function() {
var init = function(settings) {
var config = {
$wrapper : $('#explorerCategories'),
$contentHolder : $j('#categoryContent'),
loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />'
}
// provide for custom configuration via init()
if (settings && typeof(settings) == 'object') {
$.extend(config, settings);
}
// some more code...
},
var createExpanderLink = function() {
// more code
},
var anotherMethod = function() {
// etc
}
// Public API
// return the functions you want to use outside of the current instance
return {
init : init,
createExpanderLink : createExpanderLink,
anotherMethod : anotherMethod
}
}
var firstExplorer = new myExplorer();
var secondExplorer = new myExplorer();
// etc
When you call $.extend()
like this, it merges the second object's properties into the first:
$.extend(myExplorer.config, settings);
Instead, create a new object that's the result of the merge leaving the first object (the defaults) untouched, like this:
this.settings = $.extend({}, myExplorer.config, settings);
What this does is still merge the passed objects into the first, but the first is a new object ({}
), so we're not affecting either of the others, then just use this.settings
(or a different name to make it absolutely clear) inside your object.
From my understanding you are trying to create a new instance of object which was defined using object literal notation. object literals can be instantiated using Object.create method. Here is the code that explains how to instantiate an object from object literal notation.
var objLiteral = {
name:"kanthan",
address:'',
deliver:function(){
if(this.address){
console.log("Your product has been successfully delivered at "+this.address);
}
else{
console.log("please enter the address to deliver");
}
}
};
var cum=Object.create(objLiteral);
cum.address="gkm colony";
objLiteral.deliver();
cum.deliver();
var cum1=objLiteral;
cum1.address="gkm colony";
objLiteral.deliver();
cum1.deliver();
精彩评论