I have built a javascript class that does things to the dom. To simplify the use from outside as much as possible I now have methods like these:
hello.add(id);
hello.delete(id);
hello.select(id);
To make the above work, I have setup a static class that uses the non static class like this:
Static class
class hello {
static add(id) {
let hello = new HelloCore();
hello.add(id);
}
static delete(id) {
let hello = new HelloCore();
hello.delete(id);
}
static select(id) {
let hello = new HelloCore();
hello.select(id);
}
}
Non static class
The real code is 500 lines with a constructor and so on.
class helloCore() {
add() {
// Do something
}
delete() {
// Do something
}
select() {
// Do something
}
}
It's now super simple but I wonder if there is a performance issue with this approach. My guess is that it store a new javascript object on every static call into memory?
Do I need to worry about it?
If yes, what would be a better approach, but still super simple?
What I want to stay away from
From the start I had always needed to pass the object around to the functions where it's going to be used. See below.
let hello = new HelloCore();
function my_function(hello) {
let id = 2;
hello.add(id);
}
my_function(hello);
With the static approach I don't need to pass the object around everywhere. I can just trigger the function from anywhere.
I could use a global var hello = new Hello(); but then I need to make sure it's loaded first, that I don't forget about it and it means extra code for the user.
You may want to take a look at Singleton.
It does exactly what you are trying to achieve.
However, I must admit that I (and a lot of other developers) frown upon singletons, globals and static classes, not because of performance, but as a general pattern.
This SO question tells a bit about why singletons are bad.
#mareful commented this helpful information:
With the static class approach the hello instance is not available after function call any more...
It means that the static class will self clean after each call.
Then I got a comment from #Bergi with an idea to use a const including functions with the same result. This approach works really well.
Before - with static class
class hello {
static add(id) {
let hello = new HelloCore();
hello.add(id);
}
static delete(id) {
let hello = new HelloCore();
hello.delete(id);
}
static select(id) {
let hello = new HelloCore();
hello.select(id);
}
}
After - with const
const hello = {
add(id) {
new HelloCore().add(id);
},
delete(id) {
new HelloCore().delete(id);
},
select(id) {
new HelloCore().select(id);
}
};
In both cases I can call it like hello.add(id);. The const version is shorter and has some other advantages in this case as well.
it doesn't create a constructor function and prototype object that are never needed (and might even be abused, or at least will confuse the reader).
Related
Private variables are variables that are visible only to the class to which they belong. It is a common opinion that there are no strict private variables in JS (except for the new fields like this.#property).
Can anyone kindly explain why the variable 'boy' bellow cannot be considered to be a private one?
class Forrest {
constructor() {
let boy = "Bobby"
this.getBoy = function() {
console.log(boy)
}
}
}
const f = new Forrest()
f.getBoy() // Bobby
I haven't heard people claim that boy in your example isn't private. Quite the opposite, it's private to the constructor and getBoy. Nothing else (including nothing else in that class) can access it. But either way, I suppose that might be in the "opinion-based" realm.
Stepping out of that realm: Regardless of someone may feel about the closure approach shown in the question, JavaScript will have true private fields very, very soon. It's implemented in most major engines and likely to hit the spec this year. Your example with private fields looks like this:
class Forrest {
#boy = "Bobby";
getBoy() {
console.log(this.#boy);
}
}
const f = new Forrest();
f.getBoy() // Bobby
Or if we set it from a constructor parameter:
class Forrest {
#boy;
constructor(boy) {
this.#boy = boy;
}
getBoy() {
console.log(this.#boy);
}
}
const f = new Forrest("Bobby");
f.getBoy() // Bobby
Those will run on up-to-date versions of Chromium-based browsers. Safari and Firefox won't be much longer.
i've got a basic question about instancing of an object in NodeJS and different ways to declare classes.
I've saw few tutorials but no tutorial has descriped, when i should use which way or why there are different ways.
I want to create a instance of an object and have created two code-snippets which does exactly the same but with a completly different code.
My question: Do i get the same result or is there something special i cannot see that it is different and moreover, which way should i use?
ExampleA:
class ExampleA {
constructor () { }
method() {
console.log("Hello world");
}
}
module.exports.ExampleA = ExampleA;
ExampleB:
function ExampleB() {
}
NoSQL1.prototype.method = function() {
console.log("Hello world");
}
module.exports.ExampleB = ExampleB;
If i got it right, in ExampleB i just add a new function to a existing class within the "Classname.prototype.Method"
Maybe there are even more ways to go? As a C# developer i prefer the ExampleA, currently...
There's not a major difference. Javascript doesn't have traditional Classes. Everything is just an Object and the syntax of example A is basically just around because of convention and Javascript trying to cater to both OOP and functional programming.
But only the first pattern allows you to make private variables, through the use of a closure.
You get the same result.
Class is a syntactic sugar in latest version of ECMAScript(ES).
JavaScript is still prototype based, so you should be carefull about refrence on sepcial word this because for example:
class ExampleA {
constructor() {
this.text = 'Hello World!'
}
method() {
console.log(this.text);
}
}
let a = new EampleA()
a.method() // will print 'Hello World'
let m = a.method;
m() // will throw exception "Cannot read property 'text' of undefined
let b = {text: 'Hi'};
m.call(b) // will print 'Hi'
A factory class isn't the end product I am looking for but it is basically my problem boiled down. I am looking for a class we'll call foo that can be passed in another class bar as a parameter to its constructor such that when later calling fooInstance.create() it returns a new instance of bar. I can easily figure out how to make a fooInstance.create(bar) create an instance of bar. But that isn't what I need. I need each instance of the factory class to create a specific type of object. so:
fooCar = new foo(Car);
fooTruck = new foo(Truck);
myCar = fooCar.create();
myTruck = fooTruck.create();
This would be something easily handled by Generics in c#. I either get errors or I end up screwing with the prototype of foo which then changes the type created by all instances of foo.
Just return a regular object from your factory, with just one create method:
function foo (Constructor) {
return {
create: function () {
return new Constructor();
}
};
}
Check out the fiddle: http://jsfiddle.net/fR5Gz/1/
Thanks to everyone for your help. #missingno I thought the details of what I was trying to do would cloud the issue but now I think it was the other way around. I'll know better for next time. I wasn't looking for type safety but without it maybe there is no reason to do it this way. Maybe I'm stuck in classical thinking.
I actually figured it out myself this morning because I didn't get any email alerts on this thread like I was supposed to so I thought there weren't any replies yet. This is my solution (relevant code only):
ORM.Repository = (function (){
function Repository(ob){
this.construct = ob;
};
//bunch of other generic repository stuff deleted
Repository.prototype.make = function () { return new this.construct();}
return Repository;
})();
Usage:
var carRepository = new ORM.Repository(car);
var personRepository = new ORM.Repository(person);
var myCar = carRepository.make();
var user = personRepository.make();
Hullo! This is my first question!
I am experimenting with the module pattern promoted by Doug Crockford and others. Mostly very happy with it so far, but I am a little unsure about the best way of handling a certain inheritance pattern.
I have it boiled down to a bare bones case using cat and mammal, although my actual intention is to make objects for a tile based game in canvas.
But here is my bare bones 'animals' case using a browser alert:
var ZOO = ZOO || {};
//
ZOO.mammal = function () {
"use strict";
var voice = "squeak.mp3", // default mammal sound
utter = function () {
window.alert(this.voice);
};
//
// public interface
return {
utter: utter,
voice: voice
};
};
//
ZOO.cat = function () {
"use strict";
// hook up ancestor
var thisCat = ZOO.mammal();
thisCat.voice = "miaw.mp3";
return thisCat;
};
//
var felix = ZOO.cat();
felix.utter();
What bothers me about this approach is that I have had to make voice a public property so that cat can modify it.
What I really want is something like 'protected' visibility (from Java, ActionScript etc.), so that cat can modify voice without anyone with access to felix being able to modify it.
Is there a solution?
You can simulate protected visibility (visible to yourself, and child objects) by passing a blank object to your base "class" to serve as the repository for your protected properties. This will allow you to share properties through your inheritance chain, without making them public.
var ZOO = ZOO || {};
ZOO.mammal = function (protectedInfo) {
"use strict";
protectedInfo = protectedInfo || {};
protectedInfo.voice = "squeak.mp3";
// public interface
return {
utter: function () {
alert(protectedInfo.voice);
}
};
};
ZOO.cat = function () {
"use strict";
var protectedInfo = {};
// hook up ancestor
var thisCat = ZOO.mammal(protectedInfo);
protectedInfo.voice = "miaw.mp3";
return thisCat;
};
Here's a live demo
Sidesteping non-answer:
There are some ways to kind of get protected properties in Javascript but they aren't necessarily very idiomatic. If I were you I would first strongly consider either
Using the convention of public properties prefaced with an underscore (ex.: _voice) to denote privacy. Its very simple and is something of a standard among dynamic languages.
Seek an alternate solution without inheritance. Inheritance often complicates and couples stuff to much, hence the old "prefer composition over inheritance" mantra. Javascript has many features, like duck typing and higher order functions, that often let you avoid using inheritance in situations where you would normaly need it in Java
There is a workaround to simulate protected members, where you make public those members for a while, and then you privatise them again. I'm not a big fan of this, but it's a "solution".
I'm just quoting from this SitePoint article:
Adding Protected Members
Splitting a script into multiple modules is a common and convenient
practice. It makes a large codebase much easier to manage, and allows
for bandwidth savings to be made when modules aren’t always required.
But what if we want to share data between different modules? If we
make that data public then we’ll lose the benefits of privacy, but if
we make it private it will only be available to one module. What we
really need are shared private members, and these are known as
protected.
JavaScript doesn’t have protected members as such, but we can
effectively create them by making data temporarily public. To achieve
this, let me first introduce you to two key functions — extend and
privatise — which we’ll define as part of a utility-functions object:
var utils = {
extend : function(root, props) {
for(var key in props) {
if(props.hasOwnProperty(key)) {
root[key] = props[key];
}
} return root;
},
privatise : function(root, prop) {
var data = root[prop];
try { delete root[prop]; } catch(ex) { root[prop] = null; }
return data;
}
};
The extend function simply adds new properties to an object, while the
privatise function copies a property and then deletes the original. We
can use extend in one module to create a public reference to a private
variable, and then use privatise in another module to copy it back to
a private variable and delete the public reference.
So here’s an example of the first module which has two protected
members (including the utils object itself), and one public member. To
keep the code example short, the utility functions are just empty
shells, but they would be identical to the functions I showed you a
moment ago:
var MyModule = (function() {
var myProtectedData = 909;
var utils = {
extend : function(root, props) { },
privatise : function(root, prop) { }
};
this.myPublicData = 42;
return utils.extend(this, { myProtectedData : myProtectedData, utils : utils });
})();
You can see how we’re using a variant of the revealing module pattern,
to return not just the public members, but the protected members as
well. So at this point we have three public members:
MyModule.myProtectedData, MyModule.utils and MyModule.myPublicData.
Now here’s an example of the last module which uses the privatise
function to copy the specified public members back to private
variables, and then delete their public references:
var MyModule = (function() {
var myProtectedData = this.utils.privatise(this, 'myProtectedData');
var utils = this.utils.privatise(this, 'utils');
return this;
}).apply(MyModule);
And once that’s done the protected members are locked inside their
objects, privately available to both the modules, but no longer
available from outside them.
Note that the privatise function relies on having separate arguments
for the object and the property-key, because objects in JavaScript are
passed by reference. So root is a reference to MyModule, and when we
delete a property from it that’s specified by key, we’re deleting that
property from the referenced object.
But if it was like this:
privatise : function(root) {
var data = root;
try { delete root; } catch(ex) { root = null; } return data;
}
And called like this:
var myProtectedData = this.utils.privatise(this.myProtectedData);
Then the public members would not be deleted — the function would
simply delete the reference, not the property it refers to.
The try ... catch construct is also necessary for older IE versions,
in which delete is not supported. In that case we nullify the public
property rather than deleting it, which is obviously not the same, but
has an equivalent end result of negating the member’s public
reference.
I'm using the module pattern in Javascript to separate my public interface from the private implementation. To simplify what I'm doing, my code generates a chart. The chart consists of multiple parts (axises, labels, plot, legend, etc.) My code looks like:
var Graph = function() {
var private_data;
function draw_legend() { ... }
function draw_plot() { ... }
function helper_func() { ... }
...
return {
add_data: function(data) {
private_data = data;
},
draw: function() {
draw_legend()
draw_plot()
}
}
}
Some people advocate only testing the public interface of your classes, which makes sense, but I'd really like to get in some tests to test each of the components separately. If I screw up my draw_legend() function, I'd like that test to fail, not a test for the public draw() function. Am I on the wrong track here?
I could separate each of the components in different classes, for example make a Legend class. But it seems silly to create a class for what's sometimes just 5-10 lines of code, and it would be uglier because I'd need to pass in a bunch of private state. And I wouldn't be able to test my helper functions. Should I do this anyway? Should I suck it up and only test the public draw()? Or is there some other solution?
There is no way to access inner functions (private) from an outer scope. If you want to test inner functions you might consider adding a public method for testing purposes only. If you are using some sort of a build environment, for example ant, you may pre-process the javascript file for production and remove those test functions.
Actually Javascript is an Object oriented language. It's just not a statitcally typed one.
My solution is just a little bit of hack. QUnit example:
At the top of Qunit test html I have declared:
var TEST_AVAILABLE = true;
In the testable class I have a fragment like this:
if(TEST_AVAILABLE){
this.test={
hasDraft:hasDraft,
isInterpIdIn:isInterpIdIn,
// other private methods
};
}
In the QUnit you could verify
test( "hello booth", function() {
var b = new Booth();
ok(b);
ok(b.test);
ok(!b.test.hasDraft());
});
I have a similar problem. The solution I came up with is not something I like but it does the job and there's not a better solution I can find.
function Graph()
{
this.Test = function _Test(expressionStr) { return eval(expressionStr); }
var private_data;
function draw_legend() { ... }
function draw_plot() { ... }
function helper_func() { ... }
...
}
To test:
var g = new Graph();
g.Test("helper_func()") == something;
g.Test("private_data") == something2
There is an easy way actually. You can use ajax to load the script and inject a function that exposes the private functions. I have an example here that uses qUnit and jQuery. But I'm sure the same can be easily accomplished using pure Javascript.
In an object oriented language, you would typically unit test the protected methods by having the test class inherit from the class it's testing.
Of course, Javascript is not really an object oriented language, and this pattern does not allow for inheritance.
I think you either need to make your methods public, or give up on unit testing them.
There is the only one right option: Different Builds for Testing and Production
1) mark development only parts
/* test-code */
api._foo = foo
/* end-test-code */
2) strip them later... ;)
grunt.registerTask("deploy",
[
"concat",
"strip-code",
...
#philwalton has written beautiful articles:
HOW: https://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/
WHY: https://philipwalton.com/articles/why-i-test-private-functions-in-javascript/