This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Static variables in JavaScript
How can i make a static encapsulation with self members in javascript?
such as in php:
class bar{
static public $foo;
static public function set() {
self::$foo = 'a';
}
}
bar::set();
In javascript:
var bar = function () {
????????
}
bar.set();
Thanks!
Simply define them as properties of bar.
bar.foo = null;
bar.set = function() {
bar.foo = "a";
}
Here's a nice overview:
var bar = function() {
// Private instance variables
var a = 1;
// Public instance variables
this.b = 5;
// Privileged instance methods
this.c = function() {
return a;
}
};
// Public instance methods
bar.prototype.d = function() {
return ++this.b;
}
// Public static variables
bar.foo = null;
// Public static methods
bar.set = function() {
bar.foo = "a";
}
Make a closure that creates the object and returns it. Inside the closure you can declare local variables, and they are private to the scope:
var bar = (function(){
var foo;
return {
set: function(){
foo = 'a';
}
};
})();
bar.set();
Related
This question already has answers here:
Javascript "this" pointer within nested function
(9 answers)
Closed 6 years ago.
I have the following JS-Object:
var obj = function(){
this.var1 = "var1";
this.getvar1 = function(){
return this.var1;
}
this.call1 = function(){
this.getvar1();
}
}
all methods have to be public
all properties have to be public as well
Problem:
If i try to call a public method of the obj-Object from inside another public method of the obj-Object, the "this" keyword refers to the public method itself instead of the Object.
Is there a way to get around this?
You can assign this to a variable(self) and use that:
var obj = function(){
var self = this;
self.var1 = "var1";
self.getvar1 = function(){
return self.var1;
}
self.call1 = function(){
self.getvar1();
}
}
You just forgot to return from call1. Add return and it will work as expected:
var obj = function() {
this.var1 = "var1";
this.getvar1 = function() {
return this.var1;
}
this.call1 = function() {
return this.getvar1();
}
}
var a = new obj()
console.log( a.call1() )
Maybe you meant this:
const obj = {
var1: 'var1'
,getvar1() {
return this.var1
}
,call1() {
return this.getvar1()
}
}
console.log(obj.call1())
I create a class in JavaScript with public and private properties - data and methods to operate on this data. Some data is private and should not be accessible via "."(dot) operator from class instance. Is there way to avoid method duplication for every class instance?
function MyClass() {
let privateVar;
let publicVar;
function publicFun() {
// do something
}
function privateFun(){
// do something else
}
this.v = publicVar;
this.f = publicFun;
}
let obj1 = new MyClass();
let obj2 = new MyClass(); // publicFun and privateFun methods duplication
ClassName.prototype approach require completely public API for all class data. So this doesn't work for me.
Here is my example if I understood you correctly:
Methods are defined only once, within the wrapper function (thus they are not declared on every instance)
You can create instances of objects they will all refer to the same methods, and can have exposed data.
Here is a fiddle example:
function wrapper() {
//Methods defined only once
function method() {
alert("this is method");
}
function methodWithParams(param, callback) {
var paramsVar = param;
function realMethodHere() {
alert("We passed a param: " + paramsVar);
paramsVar = "Changed"
callback(paramsVar);
alert("Now we cahnged the param's value to: " + paramsVar + ", rerun the method to verify");
}
return realMethodHere;
}
//Class constructor
function classConstructor() {
//Private
var privateData = "Private"
function privateFunction() {
alert("this is some private function, inaccesible");
}
//This callback was addedto allow yo uto change private data.
function privateDataChangerCallback(param) {
privateData = param;
}
//Public
this.publicData = "Public"
this.callMethod = method;
this.paramMethod = methodWithParams(privateData, privateDataChangerCallback);
}
return classConstructor;
}
var classDefinition = wrapper();
var classInstance = new classDefinition();
classInstance.callMethod(); //method without param
classInstance.paramMethod(); //method with exposed Private data
//rerunning the method to see what the value is:
classInstance.paramMethod(); //method with exposed Private data
You can try using TypeScript it's a javascript library that support OOP so you can write your code like in c# or java and the compiler will generate the real javascript for you.
If I understand right, you can add a parameter to your class definition and based on this parameter, you can choose to include additional properties to your return object.
Sample
function myClass(option) {
var myFunc1 = function() {}
var myFunc2 = function() {}
var myFunc3 = function() {}
var myFunc4 = function() {}
var myFunc5 = function() {}
var finalProps = {
myFunc1: myFunc1,
myFunc2: myFunc2,
}
switch (option) {
case "all":
finalProps["myFunc5"] = myFunc5;
case "more":
finalProps["myFunc3"] = myFunc3;
finalProps["myFunc4"] = myFunc4;
break;
}
return finalProps;
}
(function() {
var f1 = new myClass();
var f2 = new myClass("more");
var f3 = new myClass("all");
console.log(f1, f2, f3)
})()
You can create a stand-alone function in the constructor function:
var HelloWorld = (function () {
function anonymouse() {
return "MUHAHAHA! ALL MINE!!!";
}
function HelloWorld() {
this.greeting = "Hello World";
}
//public
HelloWorld.prototype.greet = function () {
console.log("Hello, " + this.greeting + " " + anonymouse());
};
return HelloWorld;
}());
var greeter = new HelloWorld();
greeter.greet();
console.log(greeter);
But this does have the side effect of duplicating said function on all instances of your class.
Alternatively, maybe create a namespace to hide it in, and reference your functions from there. That would eliminate the duplicate function issue:
var MySecretClasses;
(function (MySecretClasses) {
function anonymouse() {
return "MUHAHAHA! ALL MINE!!!";
}
var HelloWorld = (function () {
function HelloWorld() {
this.greeting = "Hello World";
}
//public
HelloWorld.prototype.greet = function () {
console.log("Hello, " + this.greeting + " " + anonymouse());
};
return HelloWorld;
}());
MySecretClasses.HelloWorld = HelloWorld;
})(MySecretClasses || (MySecretClasses = {}));
var greeter = new MySecretClasses.HelloWorld();
greeter.greet();
console.log(MySecretClasses);
console.log(greeter);
TYPESCRIPT
As Shlomi Haver points out, you could use TypeScript for this.
module MySecretClasses {
function anonymouse() {
return "MUHAHAHA! ALL MINE!!!";
}
export class HelloWorld {
greeting: string = "Hello World";
constructor() {
}
//public
public greet() {
console.log("Hello, " + this.greeting + anonymouse());
}
}
}
var greeter = new MySecretClasses.HelloWorld();
greeter.greet();
console.log(greeter);
Suppose I need to declare some private static members to use it in some public static methods...
// ***** Variant I *****
function supports() {
var impl = document.implementation; // private, non-static
this.SVG = function () { // public, non-static
return impl.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
};
}
// ***** Variant II *****
function supports() { }
supports.prototype.impl = document.implementation; // public, non-static
supports.SVG = function () { // public, static
return impl.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
};
I know there are some difficulties in JavaScript with the 'static' OOP concept, so my question about is:
Can I declare public static methods inside the "declaration body" of the 'object' (like in the "Variant I" above)?
There is no private, static or public in JavaScript. There is only local and global, in-scope and out-of-scope. Use an IIFE to capture a variable and return a closure; this should work equivalently to a static method.
var supports = (function supportsWrapper() {
var impl = document.implementation; // "static"-ish.
return function supports() {
this.SVG = function () {
return impl.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
};
}
})();
impl will be initialised only once, and will be readable only by supports, but will persist between calls to it.
In your Variant II the function that is supposedly private and static is neither private nor static.
You are correct that it is quite difficult to define a private static member of the class, but it is possible if you exploit JavaScript's scope.
var Person = (function(){
var privateStaticProperty = true;
function privateStatic() {
return privateStaticProperty;
}
function Person(){
// class declarations
}
Person.prototype.example = function() {
return privateStatic();
}
return Person;
}());
var p = new Person();
console.log(p.example());
Note, however, that if you extend the prototype outside of the closure, the supposedly private static members will not be available.
In JavaScript, there is no term or keyword static, but we can put such data directly into function object (like in any other object).
Static methods
Static methods, just like variables, are attached to functions. They are used mostly for objects:
function Animal(name) {
arguments.callee.count = ++arguments.callee.count || 1
this.name = name
}
Animal.showCount = function() {
alert( Animal.count )
}
var mouse = new Animal("Mouse")
var elephant = new Animal("elephant")
Animal.showCount() // 2
The only solution I see after analyzing some answers is this one:
var Person = (function () {
var _privateStatic = 'private static member';
function privateStatic() {
return _privateStatic + ' + private-s-function';
}
function Person() {
this.publicNonStatic = 'public, non-static member';
this.publicFunction = function () {
return this.publicNonStatic + '+ public non-static-function';
}
var _privateNonStatic = 'private, non-static member';
function privateNonStatic() {
return _privateNonStatic + " + private-ns-function"
}
this.publicStatic = Person.publicStatic = 'public static member';
this.publicStaticFunction = Person.publicStaticFunction = function () {
return Person.publicStatic + ' + public static function';
}
// Accessible internal
var test = _privateNonStatic;
test = _privateStatic;
test = privateStatic();
test = privateNonStatic();
// other class declarations
}
return Person;
}());
// Accessible external members:
var p = new Person();
console.log(p.publicFunction());
console.log(p.publicNonStatic);
console.log(p.publicStatic);
console.log(p.publicStaticFunction());
console.log(Person.publicStatic);
console.log(Person.publicStaticFunction());
PS.
I remarked however that publicStaticFunction() becames accesible only after a new Person() declaration... so, before it they are not available:
// Accessible external members:
console.log(Person.publicStatic); // NO WAY
console.log(Person.publicStaticFunction()); // NO WAY
var p = new Person(); // lazy declaration
console.log(Person.publicStatic); // IS OK!
console.log(Person.publicStaticFunction()); // IS OK!
, so I suppose there is no way to achieve it INSIDE the function Person body, only inside the anonymous function that wraps the Person...
So the initial SVG sample should be like this:
var supports = (function(){
function supports() { this.SVG = supports.SVG; }
supports.SVG = function () {
return document.implementation.hasFeature("http://shortened", "1.1");
};
return supports;
}());
// usage of public, static method
if (supports.SVG()) {return 'supports SVG!';}
I use the following Singleton pattern in JavaScript:
var exampleClass =(function(){
//private
var a ="test";
function PrivateMethod()
{
return a;
}
//public
return{
Test: function() {
alert(PrivateMethod());
}
}
})();
As I read through StackOverflow I see a lot of other implementations of Singleton and I start to doubt if I couldn't make mine better.
I hope someone can tell me what's right or wrong about doing it this way.
It depends what you want to achieve as the different implementations will have different benefits and limitations.
The simplest implementation is just an object literal:
var singleton = {
property: "foo",
method: function() {
alert('bar');
}
}
The implementation you mention in the question allows public and private methods by encapsulating the methods in a closure and returning what should be exposed.
Here is an alternative which similarly would allow public and private methods and is more extensible:
function MySingletonClass() {
if ( arguments.callee._singletonInstance )
return arguments.callee._singletonInstance;
arguments.callee._singletonInstance = this;
this.Foo = function() {
// ...
}
}
var a = new MySingletonClass()
var b = MySingletonClass()
Print( a === b ); // prints: true
This is mine.
Differences are:
all functions declared at top
all functions are private by default
all functions have access to other functions
public functions are mapped at bottom
Improvements are:
if you want to move a function from private to public or viceversa, you don't have to move code, only change mapping at bottom of code
all functions have access to both private and public functions (because all functions are private by default)
var exampleClass =(function(){
//private
var a ="test";
//declare here all functions
//(both for pass jslint validation and is good to have a list
//of all available functions, in case of classes with a lot of code
var PrivateMethod,
Test1,
Test2;
PrivateMethod = function()
{
return a;
};
Test1 = function()
{
return PrivateMethod();
};
Test2 = function()
{
return Test1();
};
//public
//Expose function you want to have pubblic
return{
Test1: Test1,
Test2: Test2
}
})();
I'm using this pattern:
var SingletonConstructor;
(function() {
var instance;
SingletonConstructor = function() {
if (typeof instance !== 'undefined')
return instance;
var a = "a";
function PrivateMethod() {
return a;
}
return instance = this;
};
})();
This is how Google Closure do it:
http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/base.js#427
I love the following pattern:
function MyClass(){
if(MyClass.instance){
return MyClass.instance;
}
MyClass.instance = this;
//constructor code goes here
}
var a = new MyClass();
var b = new MyClass();
console.log(a == b); //true
I was going through some code written by Douglas Crockford. He uses the below structure to create objects.
var obj = (function(){
var x, y, z; // These are private fields
// This is private method
function func1() {
}
return {
// This is public method
init : function() {
}
};
}());
I like this way as opposed to the constructor functions like below.
function Obj() {
// Uses __ to denote private
this.__x = 0;
this.__y = 0;
this.__z = 0;
// Private method
this.__func1 = function() {
};
// Public method
this.init = function() {
}
}
var obj = new Obj();
I don't like the constructor function method as you need to use __ for denoting private fields or methods (and this does not really make the field private) and you need to use this keyword for accessing any field or method. I like the first method but I don't know how to define multiple objects using it.
Can we define multiple objects in the first method or it can only be used for creating singleton objects?
To instantiate new objects you need to use the new keyword that needs to use a function as a constructor. I see 2 options:
Return a function instead of object literal in your function:
var obj = (function(){
var x, y, z; // These are private fields
// This is private method
function func1() {
console.log("func1");
}
return function() {
// This is public method
this.init = function() {
func1();
}
};
})();
Or don't use a self executing function:
var obj = function(){
var x, y, z; // These are private fields
// This is private method
function func1() {
console.log("func1");
}
return {
// This is public method
this.init = function() {
func1();
}
};
};
Both let's you do var newObj = new obj(). Not sure what are the implications between the two but I normally just use a function.
Just a note that:
this.__x
does not make x private (except possible by convention, i.e people learn not to use that)
rather:
function Obj() {
// private
var x = 0;
var __y = 0;
// public
this.z = 0;
// Private method
function func1() {
};
// Public method
this.init = function() {
}
}
I found this link helpful: http://www.phpied.com/3-ways-to-define-a-javascript-class/