Im creating a new library for a company. The structure I follow is
(function() {
var lib = function() {
//some private and public fn definitions
//setting publically avbl functions
return {
func1 : func1, func2: func2
};
};
return (window.lib = lib);
})();
Now how I call this is
lib.func1();
I want to be able to call my library as
lib(function | string | object).someproperty
How do I convert my code. Tried something like this
function lib() {
return new arguments.callee(arguments);
}
lib.prototype={
publicfunc: function() {
}
}
In this i'm having some problems accessing private functions since it is out of the scope for the public functions defined in the lib's prototype.
var lib = (function (param) {
var func = function () {
/// your code
return {
animate : function () {
// do the animation
return this;
}
}
return func;
})();
this can be the basic fprmat.
ok here is how i can be used.
lib(function() {...});
or
lib(selectItem).animate();
because i returned this i can run another method if there is any.
lib(selectItem).animate().animate().animate().animate() ....;
i hope you can find a use of this format, of course i made it very basic
In this i'm having some problems accessing private functions since it is out of the scope for the public functions defined in the lib's prototype.
This is because there is no such thing as private there is only local. You cannot access local variables out of scope.
The prototype cannot talk to local variables in the constructor. There are various hacks around this like keeping a public hash of instances but then you lose the "privacy"
Related
Building a best practices for a manual on Module Patterns (for an internal's firm course) We come to the needs of easy discussion on the public contract and the persistence of each object. So the team is divided between two structures:
CLASSIC:
// Namespace for the library
var myFunPattern1 = {};
// Library definition
myFunPattern1 = (function () {
// Private variables / properties
var myPrivateVar = "anyValue"
// Private methods
function anyPrivateMethod(parameter) {
...
return "whatever";
}
// Public API
return {
anyPublicMethod: function (parameter) {
...
return "whatever";
}
};
})();
THE OTHER:
// Namespace for the library
var myFunPattern2 = {};
// Library definition
myFunPattern2 = (function () {
// Public API
return {
anyPublicMethod: internalNameForPublicMethod
};
// Private variables / properties
var myPrivateVar = "anyValue"
// Public methods
function internalNameForPublicMethod(parameter) {
...
return "whatever";
}
// Private methods
function anyPrivateMethod(parameter) {
...
return "whatever";
}
})();
we see the first of more "code elegant" while the second enables faster development and clear conversation between teams (once the return is defined with the documentation for parameters and so on, each developer can start working on the rest of the code
also, changes on the functionality (i.e A/B testing on function performance), on first mode need to be changed the function, on second, only the internal reference. Even, that may could be done dynamically ...
some of us think the second may raise some inconsistencies and force dependencies (public functions being declared first, or invoque before declaration), others we think we are safe ...
any other consideration??
Because of angular factories, I am thinking about using a class that uses some methods that are on its closure as if they were private methods.
This is not 100% classical inheritance nor revealing pattern, so I'm not sure if this is correct or not. Here is a small example:
myClass = (function() {
function privateMethod (stuff) { return something }
function TheClass () { this.someValue = 'Hello'}
TheClass.prototype.someMethod = function () { return privateMethod(this.someValue)}
return TheClass
}());
And then do something like
instance = new myClass()
I think this works fine for helper functions or private methods that do not change the values of the instantiated object. Using private "variables" may be useful for singelton classes or maybe fixed values.
Is there any problem with this implementation?
That's typically fine to do and its essential that most classes depend on their closure. Usually your class will be in its own file - its own module. If you are using a module loader (I hope you are), then closure is already implied and the methods are already "private" when defined like this:
// Begin MyClass.js
function privateMethod (stuff) { return something }
function TheClass () { this.someValue = 'Hello'}
TheClass.prototype.someMethod = function () { return privateMethod(this.someValue)}
// depending on which module loader you are using
return TheClass;
module.exports = TheClass;
export default TheClass;
In TypeScript, I can't seem to declare a function in a class without the compiler adding it to the prototype. For example:
class MyTypeScriptClass {
// method, is added to prototype
foo1(): void {
alert('invoked foo1');
}
// private method also added to prototype
private foo2(): void {
alert('invoked foo2');
}
//// can I have a local function, without making it a private method?
//function foo3() {
// alert('invoked foo3');
//}
}
The above compiles to this:
var MyTypeScriptClass = (function () {
function MyTypeScriptClass() { }
MyTypeScriptClass.prototype.foo1 = function () {
alert('invoked foo1');
};
MyTypeScriptClass.prototype.foo2 = function () {
alert('invoked foo2');
};
return MyTypeScriptClass;
})();
What I am looking for is typescript that can compile to the following JavaScript:
var fvm = new FlasherViewModel2();
var MyTypeScriptClass = (function () {
function MyTypeScriptClass() { }
MyTypeScriptClass.prototype.foo1 = function () {
alert('invoked foo1');
};
MyTypeScriptClass.prototype.foo2 = function () {
alert('invoked foo2');
};
function foo3() {
alert('invoked foo3');
}
return MyTypeScriptClass;
})();
Can it be done?
(As a side note, I know that foo3 would not be callable from external code. I would actually invoke foo3 from another method within the class, for example, to pass a function to a jQuery fadeOut.)
As apsillers mentions, private static is probably what you want. While it's not supported in current builds, you will be able to have a private static member in TypeScript at some point in the future (the design team changed its mind on this one based on feedback similar to this).
I just discovered another way to have private methods in a typescript class, though the pattern may smell a little funny. As far as I can tell, you can only do this when you wrap the class in a module. For example:
module MyApp {
// not accessible externally, `this` must be passed in if needed
function foo3(that: MyTypeScriptClass): void {
that.foo1();
alert('invoked foo3');
}
// not accessible externally
function foo4(): void {
alert('invoked foo4');
}
export class MyTypeScriptClass {
// normal method, is added to prototype
foo1(): void {
alert('invoked foo1');
}
// private method also added to prototype, is accessible externally
private foo2(): void {
alert('invoked foo2');
foo3(this);
foo4();
}
}
}
The above compiles into:
var MyApp;
(function (MyApp) {
function foo3(that) {
that.foo1();
alert('invoked foo3');
}
function foo4() {
alert('invoked foo4');
}
var MyTypeScriptClass = (function () {
function MyTypeScriptClass() { }
MyTypeScriptClass.prototype.foo1 = function () {
alert('invoked foo1');
};
MyTypeScriptClass.prototype.foo2 = function () {
alert('invoked foo2');
foo3(this);
foo4();
};
return MyTypeScriptClass;
})();
MyApp.MyTypeScriptClass = MyTypeScriptClass;
})(MyApp || (MyApp = {}));
With the above, external javascript could invoke foo2() on an instance of MyTypeScriptClass, but neither foo3() nor foo4() is accessible externally at runtime. The biggest caveat is that if your private method needs access to members of the instance, you have to pass this in as a function parameter. Essentially, these are private static methods.
var instance = new MyApp.MyTypeScriptClass();
// public, accessible externally
instance.foo1();
// will not compile in a .ts file, but works at runtime from manual js file
instance.foo2();
// runtime exception, foo3 is not defined
foo3(instance);
MyApp.foo3(instance);
// runtime exception, foo4 is not defined
foo4();
MyApp.foo4();
This approach also sort of works with scalar variables, but the variables are also essentially static -- you can't have different values for different class instances. To do that, as far as I can tell, you still need to declare them within the class. Marking them private will keep the typescript compiler from allowing external calls to them, but other javascript code can still access them externally.
In my application,I have to build a standalone lib for other people use,so I create new object like this:
function MyService(){
//xxxxxxx...
}
MyService.prototype.login=function(name,pass){
//here
}
MyService.prototype.LoadDataFromServer(){
//use the ajax get data from server,when get the data,I will eval them :
var data=parseData(request.responseText);
//now,the parseData is a private method which should not be exposed to the user,but it need the reference of the MyService object(this),so I have to use the following code:
var this_ref=this;
function parseData(res){
this_ref.xxxx=.....
}
}
MyService.prototype.parseData=function(res){
this.xxxxx=....
}
This will make the paresData function to the user.
Now,I wonder which is better?
If you want actually private data/methods you should be using closures better.
var MyService = (function() {
// define "private" methods
var _login = function(name, pass) {
...
},
_loadDataFromServer = function() {
....
},
_parseData = function(res) {
...
};
//return "public" methods
return {
login: _login,
loadDataFromServer: _loadDataFromServer
};
}()); // execute function immediately
MyService now only has the two "public" functions, login and loadDataFromServer you can still access the "private" functions from the public functions but you cannot directly access any of the "private" methods MyService._login('test','pass'); will fail but MyService.login('test','pass'); will work. See this example http://jsfiddle.net/EXrDW/
There is no "better" answer, only what you feel more comfortable with. What a lot of people seem to have adopted is the practice of putting underscores in front of methods that shouldn't be accessed by users.
After reading a bit on Javascript's prototypical inheritance model, I change my style of constructing a class from
var Some_Class = function() {
this.public_method = function() {
};
(function() {
// constructor
}).call(this)
}
to
var Some_Class = function() {
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
};
Although I understand that this is a good practice, but I am not allowed to access private methods from the public method anymore
var Some_Class = function() {
var private_member = 'whatever';
(function() {
// constructor
}).call(this)
}
Some_Class.prototype.public_method = function() {
return private_member; // not possible
};
After reading through an article here (Closure-created constructor), then I came out with this
var Some_Class = function() {
var private_member = 'whatever',
private_method = function(_some_value) {
// private method implementation
};
if(!arguments.callee.prototype.public_method) {
arguments.callee.prototype.public_method = function() {
private_method.call(this, private_method);
};
}
(function() {
// constructor
}).call(this)
}
However, what are the drawbacks of doing this?! or is there a better way of doing this if I want to access private member in the public method?
My answer is a non-answer: there's no built-in private access in JavaScript but that's okay because YAGNI. Here's how I make private members in my code:
function Some_Class() {
this._private_member = 'whatever';
}
Some_Class.prototype._private_method = function() {
};
That's good enough. It's not really worth it to jump through hoops when the only real purpose of private is to protect yourself from... yourself.
(I say this having spent many hours myself playing around with every permutation of closures and prototyping, just as you are, and finally saying "screw it, it's not worth it".)
The use of function scope variables and closures to simulate private variables/functions is a well established idiom in the javascript community. If the variable is truly intended to be private, I see no drawback to this approach (although some claim that performant code on certain browsers/hosts has to pay attention to how many closures get created).
In your example, the private_method (and its environment) is shared across all objects - since your public_method closure is created only the first time the object is constructed (and bound to the constructor's prototype property that sets the created object's internal prototype chain) - so the private_method that is used is only the one that was created the first time.
Here is some sample code that will help illustrate what is going on:
var global = 1;
var Some_Class = function() {
var private_method = 'whatever';
var now = ++global;
print("outer now: " + now );
private_method = function(_some_value) {
// private method implementation
print("inner now: " + now);
};
if(!arguments.callee.prototype.public_method) {
arguments.callee.prototype.public_method = function() {
private_method.call(this, private_method);
};
}
(function() {
// constructor
}).call(this)
}
new Some_Class().public_method(); // outer now: 2, inner now: 2
new Some_Class().public_method(); // outer now: 3, inner now: 2
new Some_Class().public_method(); // outer now: 4, inner now: 2
Are you sure that is what you want?
If your private_method does not need to refer to the enclosing object's state, then I see little benefit in doing things the way you are doing.
What I usually do (if i have to use 'new' to create my object) is the following:
function MyClass() {
var private_var = 1;
function private_func()
{
}
this.public_func = function()
{
// do something
private_func();
}
this.public_var = 10;
}
var myObj = new MyClass();
The downside to this approach is that each time you construct the object via 'new' you re-create all the closures. But unless my profiler tells me that this design choice needs to be optimized, i prefer its simplicity and clarity.
Also I don't see the benefit in your code of doing the following either:
(function() { }).call(this); // call the constructor
Why are you creating a separate scope in your constructor?
If you have not done so already have a look at this JavaScript Module Pattern, which allows you to access private methods and variables from within the public functions, etc.
Echoing John Kugelman: It's impossible to create private members in javascript. Live with it. Even if you create a enclosure like this:
function SomeClass() {
var _private = 0;
this.public_acessor = function() {return _private};
}
Any user can still write:
SomeClass._not_private_anymore = 1;
SomeClass.public_acessor = function () {return this._not_private_anymore};
In the end, you can't trust any public member to be the same you declared. If someone is up to break your code, he will! Another user won't break your code only because it's useful.
Works with prototype, not just singleton. Problem is, when it's time to subclass, my subclass has no access to the privates