1

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.

7
  • So if I understand right, you wish to have conditional approach for available functions in different instances of same function. Am I right? Commented Jul 7, 2016 at 10:55
  • 1
    I have been dabbling with these things for quite a while and I have managed to make it work perfectly fit to an OOP model (without the use of ES6 though, that completely reworks how we would write it), but i do not understand what your question/issue is? Commented Jul 7, 2016 at 10:57
  • can you show example of your class? and show what exactly you want to hide. Commented Jul 7, 2016 at 11:02
  • Same functions. Just like in C++ classes for example. When we create class instance there are on additional memory allocation for functions, only for data. here we create separate instance for every method described in the class. So I would like to care about memory usage only. Commented Jul 7, 2016 at 11:03
  • I still do not understand your question properly, but if you wish to remove duplication of function, using prototype should do it. Right? Commented Jul 7, 2016 at 11:05

4 Answers 4

2

Here is my example if I understood you correctly:

  1. Methods are defined only once, within the wrapper function (thus they are not declared on every instance)
  2. 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
Sign up to request clarification or add additional context in comments.

13 Comments

If I understood this example correctly, here we have the same problem: every method you declared in wrapper here duplicates for every new(wrapper())(); call. Is't it?
You are right, my mistake, updated the example and the code to reflect it NOT to happen. Like this it should work. This way wrapper is called only once, the class definition is called multiple times, so every instance is made again, but methods are only made once.
Hmmm... But what would we see if privateData variable we pass to the methodWithParams is not an Object type (number, string, bool)? methodWithParams will receive a copy of privateData but not a reference.
I am not sure what are you aiming at. At the time of the constructor, the method methodWithParams is being run, parameters you defined are being passed to it, this is run only once the constructor is called. The result of the method is a function call as defined by realMethodHere which keeps whatever parameter you passed onto the methodWithParams at the time of object initialization. If you pass a reference such as an Object or an Array, the realMethodHere has a reference, if you pass a value, such as a number, bool or string, the realMethodHere gets the value.
Sure, but if we would try to change the non-Object type variable passed to the methodWithParams it would change only local copy (inside a methodWithParams function scope) but not the variable of class object. So when the variable copied by methodWithParams() call, it is not anymore reference to variable of the class instance. They just independent!
|
1

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.

Comments

0

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)
})()

Comments

0

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);

1 Comment

For me it is very complex code! Very hard to maintain!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.