Can I add a method to a closure
This is sort of what closures are meant to avoid, but I'm wondering if there's a way to a add a method to a closure. Basically I have a js file library that I'd like to augment for a specific client by adding a new method.
I have a js file called library:
var LIBRARY = (function(){
var name;
return {
setName: function(n) { name = n; }
}());
but for a new clie开发者_运维知识库nt I want to give them a new js file that will just augment LIBRARY, adding a new function:
function(first, last){
name = first + " " + last;
}
I don't want to have to modify the library js though. Is there any way to append this function to LIBRARY so that the function has the necessary access to the name variable?
No, unfortunately you can't — or at least, not in a reasonable way. Only the functions defined within that closure will have access to that local variable.
The unreasonable way to do this would be to play games with eval
, but I'd strongly advise against it.
All you can do is add functions to LIBRARY
that don't need direct access to that variable.
Not sure exactly how you envisioned the "appending", but this works
// Base
var LIBRARY = (function(){
var name;
return {
setName: function(n) { name = n; }
, getName: function() { return name; }
}
}());
// Extension
LIBRARY.setFullName = function( first, last )
{
this.setName( first + " " + last );
}
// Test
LIBRARY.setFullName( 'Peter', 'Bailey' );
alert( LIBRARY.getName() );
So I just wanted to leave a note on how I actually accomplished this because it underscores a different way of thinking about architecture in JS.
As mentioned, I wanted to be able to augment my library with client-specific functions. What I ended up doing was modifying my library to read something like:
var LIBRARY = (function(){
var name;
var settings;
return {
init: function(options){
jQuery.extend(settings, options); // just merges two objects together
}
setName: function(n) { name = n; }
custom: function(){
if (!settings.custom || typeof(settings.custom == 'function'))
return;
name = settings.custom.apply(this, arguments);
}
}());
Then the client library augments my LIBRARY with a function like so:
LIBRARY.init({ custom: function(first, last) {
return first + " " + last;
} });
so now client code can call:
LIBRARY.custom("static", "hippo");
and name will be set to "static hippo"
精彩评论